edited by
1,228 views
1 votes
1 votes

I am getting segmentation fault for the following code.Please help to rectify.
 

#include <stdio.h>
#include <stdlib.h>
struct person {
   int age;
   float weight;
   char *name;
};

int main()
{
     struct person *ptr;
     int i, num;

       printf("Enter number of persons: ");
   scanf("%d", &num);
    
     ptr = (struct person*) malloc(num * sizeof(struct person));
   // Above statement allocates the memory for n structures with pointer personPtr pointing to base address */

      ptr->name=(char*)malloc(num*sizeof(char));

      for(i = 0; i < num; ++i)
   {
       printf("Enter name, age and weight of the person respectively:\n");
       scanf("%s%d%f",&ptr->name[i], &(ptr+i)->age, &(ptr+i)->weight);
   }

     printf("Displaying Infromation:\n");
      for(i = 0; i < num; ++i)
       printf("%s\t%d\t%.2f\n", ptr->name[i], (ptr+i)->age, (ptr+i)->weight);

   return 0;
}
edited by

2 Answers

6 votes
6 votes

There are some conceptual problems. Let me explain your code only. 

#include <stdio.h>
#include <stdlib.h>
struct person {
   int age;
   float weight;
   char *name;
};
// You have defined struct correctly Now move further

int main()
{
    struct person *ptr;
    int i, num;

    printf("Enter number of persons: ");
    scanf("%d", &num);
    // Here you have taken the number of persons, whos record you are going to 
    // create. Cool upto this.
    
    ptr = (struct person*) malloc(num * sizeof(struct person));
    // Above statement allocates the memory for n structures with pointer personPtr pointing to base address
    // Abosolutely above line do that
    
    ptr->name=(char*)malloc(num*sizeof(char));
    // In the above line you are trying to create assign memory to the pointers
    // which are pointing to name "name" field. Here you have done a mistake. See 
    // your code is only assigning memory to the first structure variable.
    
    
    for(i = 0; i < num; ++i)
    {
       printf("Enter name, age and weight of the person respectively:\n");
       scanf("%s%d%f",&ptr->name[i], &(ptr+i)->age, &(ptr+i)->weight);
       // Here in scanf, you again done mistake..
   }

     printf("Displaying Infromation:\n");
      for(i = 0; i < num; ++i)
       printf("%s\t%d\t%.2f\n", ptr->name[i], (ptr+i)->age, (ptr+i)->weight);
        // Here again make some changes
   return 0;
}

Here, i have corrected this

#include <stdio.h>
#include <stdlib.h>
struct person {
   int age;
   float weight;
   char *name;
};

int main()
{
    struct person *ptr;
    int i, num;

    printf("Enter number of persons: ");
    scanf("%d", &num);

    ptr = (struct person*) malloc(num * sizeof(struct person));

    for(i = 0; i < num; i++){
           ptr[i].name = (char*)malloc(50*sizeof(char));
    }


    for(i = 0; i < num; ++i)
    {
       printf("Enter name, age and weight of the person respectively:\n");
       scanf("%s %d %f",ptr[i].name, &ptr[i].age, &ptr[i].weight);
   }
    printf("Displaying Information:\n");

    for(i = 0; i < num; ++i)
        printf("%s\t%d\t%.2f\n", ptr[i].name, ptr[i].age, ptr[i].weight);

   return 0;
}

Enjoy :) :) 

edited by
1 votes
1 votes

Here is one version of the corrected code:

#include <stdio.h>
#include <stdlib.h>
#define NAME_SIZE 30
struct person {
   int age;
   float weight;
   char *name;
};

int main() {
    struct person *ptr;
    int i, num;

    printf("Enter number of persons: ");
    scanf("%d", &num);
    
    // ptr is pointer 
    ptr = (struct person*) malloc(num * sizeof(struct person));


    // we must allocate memory for char* member of person struct
    // in case of  char *p = "hello" it is ok !
    // but in case of runtime scanf("%s",p) it will not work without memory allocation
    //
    // because there must be some valid place to write the std_input string
    // Here char *p = "hello" compiler takes care of string literal to 
    // store in a read only memory
    // but in runtime scanf("%s",p) : there is no role of compiler : we must have some 
    // memory to write into
    for(i=0;i<num;i++) {
        ptr[i].name = malloc(NAME_SIZE*sizeof(char));
    }

    printf("Enter name, age and weight of the person respectively:\n");
    
    // ptr[i]  = *(ptr+i) = is a person type varibale stored in (ptr+i) location

    for(i = 0; i < num; ++i) {
        scanf("%s%d%f",ptr[i].name, &(ptr[i].age), &(ptr[i].weight));
    }

    printf("Displaying Infromation:\n");

    for(i = 0; i < num; ++i)
        printf("%s\t%d\t%.2f\n", ptr[i].name, ptr[i].age, ptr[i].weight);

   return 0;
}

Output :
Enter number of persons: 2
Enter name, age and weight of the person respectively:
abc
12
20.5
xyz
13
21
Displaying Infromation:
abc	12	20.50
xyz	13	21.00

Another version :

#include <stdio.h>
#include <stdlib.h>
#define NAME_SIZE 30

struct person {
   int age;
   float weight;
   char *name;
};

int main() {

    struct person *ptr;
    int i, num;

    printf("Enter number of persons: ");
    scanf("%d", &num);
    
    struct person * db[num];

    printf("Enter name, age and weight of the person respectively:\n");

    i = 0;
    while(i < num) {
      db[i] = malloc(sizeof(struct person));
      db[i]->name = malloc(NAME_SIZE*sizeof(char));
      scanf("%s%d%f",db[i]->name, &(db[i]->age), &(db[i]->weight));
      i++;
    }

    printf("Displaying Infromation:\n");
    
    for(i = 0; i < num; ++i)
        printf("%s\t%d\t%.2f\n", db[i]->name, db[i]->age, db[i]->weight);

   return 0;
}
 
//output :
Enter number of persons: 2
Enter name, age and weight of the person respectively:
abc
12 
20.5
xyz
13
21
Displaying Information:
abc	12	20.50
xyz	13	21.00

But none of the above code is leak free:

So we need to de_allocate memory from heap:

for the first version :

    // add this piece of code
    for(i=0;i<num;i++) {
        free((ptr+i)->name);
        free(ptr+i);
    }

And for the second version :

    // add this piece of code
    for(i=0;i<num;i++) {
      free(db[i]->name);
      free(db[i]);
    }

We can use  valgrind ./a.out to check memory statistics of the program executable a.out

Related questions

0 votes
0 votes
0 answers
3