0

I am getting the segmentation faults Unable to rectify it...........

If function is used (multi line commented at the top) im finding segemntation fault With the present code i am unable to guess the segmentation fault.

If fixed size of string like malloc is used then it works very fine.

//Array of pointers method
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int count=0;
char *** input(char ***);
void print(char ***);
/*
void *allocate(char *p,int j)
{
    int i=0;
    do
    {
        p=realloc(p,i+1);
//      printf("p[count][j]= %u\n",p);
        p[i]=getchar();
    }while(p[i++]!=10);
    p[i-1]='\0';
    return p;
 }*/
void save(char ***p)
{
    int j,i;
    FILE *fp;
    fp=fopen("Secret.c","w");
    for(i=0;i<count;i++)
      for(j=0;j<3;j++)
    {
      fprintf(fp,"%s\n",p[i][j]);

  } 
 fclose(fp);

}
void main()
{
    char ***a=0;
    char ch;
//  printf("a = %u\n ",a);
    while(1)
    {
        if(count>0)
        {
            printf("a = %lu\n",a);
            printf("*a = %lu\n",sizeof(*a));
            printf("**a = %lu\n",sizeof(**a));
            printf("***a = %lu\n",***a);
        }
        printf("\n\n\t\t\tMenu\n\n\n");
        printf("i . input\ns . save\np . print\nq . quit");
        printf("\n\nEnter your choice : ");
        scanf(" %c",&ch);
        getchar();
        switch(ch)
        {
            case 'i': a=input(a);break;
            case 's': save(a);
            case 'p': print(a);break;
            case 'q': return;
            default : printf("\n\n\t\t!!! Invalid choice  \n\n");
        }
    }
}
char *** input(char ***p)
{
    int i=0,j;

//  printf("p = %u\n ",p);
    p=realloc(p,sizeof(p)*(count+1));
//  printf("p = %u\n ",p);
//  printf("sizeof(p) = %u\n",sizeof(p));
//  printf("*p = %u\n ",*p);
    for(j=0;j<3;j++)
    {
        p[count]=realloc(p[count],sizeof(p)*(j+1));
//      printf("*p = %u\n ",*p);
//      printf("**p = %u\n ",**p);
        i=0;
        if(j==0)
            printf("Enter the %d name : ",count+1);
        else if (j==1)
            printf("Enter the %d mobile no : ",count+1);
        else
        printf("Enter the %d E-mail : ",count+1);    
//      p[count][j]=malloc(20);
//      gets(p[count][j]);      

//      p[count][j]=allocate(p[count][j],j);
        do
        {
            p[count][j]=realloc(p[count][j],i+1);
            p[count][j][i]=getchar();
        }while(p[count][j][i++]!=10);
        p[count][j][i-1]='\0';
//      printf("***p = %u %s\n ",***p,***p);
    }
    count++;
    return p;   

}
void print(char ***p)
{
    int j,i;
    for(i=0;i<count;i++,printf("\n"))
        for( j=0;j<3;j++)
            printf("p[%d][%d] : %s\t",i,j,p[i][j]);

}
3
  • p=realloc(p,sizeof(p)*(count+1)) I am pretty sure you should take a size of something else than p here... Commented Aug 19, 2016 at 14:05
  • You want to allocate some reasonably anticipated number of p to begin with and then realloc some reasonably anticipated additional number of p if your original limit is reached. Do not realloc for every element you add. (you can, but your are killing your efficiency with repeated calls to realloc) Commented Aug 19, 2016 at 16:15
  • Obligatory 3-star-programmer joke: c2.com/cgi/wiki?ThreeStarProgrammer Commented Aug 19, 2016 at 16:37

1 Answer 1

2

Some general guidelines:

You want to (re)allocate N instances of the type that p points to, not N instances of the type of p, so the operand to sizeof should be *p:

p = malloc( sizeof *p * N ); // operand of sizeof is *p, not p
                   ^^

If p is an array of pointers, use

p[i] = malloc( sizeof *p[i] * N );

Also, remember that a realloc call will return NULL if the memory cannot be extended, so you don't want to assign the result directly back to p, otherwise you risk losing the pointer to the memory you've already allocated, leading to a memory leak. Assign the result back to a temporary of the same type as p:

T *tmp = realloc( p, sizeof *p * M );
if ( tmp )
{
  p = tmp;
}

realloc is a potentially expensive call, and lots of little reallocs can lead to internal memory fragmentation. It's better to allocate in larger chunks than to extend one element at a time. For reading an individual input, you could so something like this:

char *getNextLine( FILE *inputStream )
{
  char staticBuffer[SOME_BUFFER_SIZE] = {0};
  char *dynamicBuffer = calloc( SOME_BUFFER_SIZE, sizeof *dynamicBuffer );
  size_t dynamicBufferSize = SOME_BUFFER_SIZE;
  bool done = false;

  /**
   * If the initial allocation fails, we have real problems.
   */
  assert( dynamicBuffer != NULL );

  while ( !done && fgets( staticBuffer, sizeof staticBuffer, stdin ) )
  {
    /**
     * Check for the newline; if it's there, remove it and set the
     * done flag to exit the loop.
     */
    char *newline = strchr( staticBuffer, '\n' );
    if ( (done = (newline != NULL)) )
    {
       *newline = 0;
    }

    /**
     * Do we need to extend our dynamic buffer?
     */
    if ( strlen( dynamicBuffer ) + strlen( staticBuffer ) > dynamicBufferSize )
    {
      /**
       * Yes.  Double the size of the dynamic buffer.
       */
      char *tmp = realloc( dynamicBuffer, sizeof *dynamicBuffer * ( dynamicBufferSize * 2 ) );
      if ( tmp )
      {
        dynamicBuffer = tmp;
        dynamicBufferSize *= 2;
      }
      else
      {
        // could not extend buffer, print an error and return what we have
        fprintf( stderr, "ERR: Could not extend dynamic input buffer\n" );
        return dynamicBuffer;
      }
    }

    strcat( dynamicBuffer, staticBuffer );
  }

  return dynamicBuffer;
}
Sign up to request clarification or add additional context in comments.

1 Comment

But if i use it like fixed size i.e // p[count][j]=malloc(20); then no segmentation fault occurs If p is an array of pointers, use p[i] = malloc( sizeof *p[i] * N ); that is what i used p[count]=realloc(p[count],sizeof(p)*(j+1)); wats the difference among the two above statements

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.