-1

I'm observing segmentation fault, when I try to allocate memory to a structure.

After memcpy() I'm trying to copy the contents of one more structure to the above structure.

Below is the code snippet :

struct student {
    char *username;
    char *id;
    int roll;
};

struct db {
    struct student *s1;
    struct student *s2;
};

void print_struct(struct student *);

int main (void) {
    struct student *student1, *student2;
    struct db *db1;
    char *name = "ram";
    char *id = "200ABCD";
    int roll = 34;

    student1 = (struct student *)malloc(sizeof(struct student));
    student1->username = name;
    student1->id = id;
    student1->roll = roll;

    printf("\nStudent 1\n");
    print_struct(student1);

    printf("\nStudent 2\n");
    student2 =student1;
    print_struct(student2);

    printf("\nDb of s1\n");
    db1->s1 = (struct student *)malloc(sizeof(struct student));  ===> segfault here
    db1->s1 = student1;
    print_struct(db1->s1);

    return 0;
}

void print_struct(struct student *s) {
    printf("Name: %s\n", s->username);
    printf("Id: %s\n", s->id);
    printf("R.No: %d\n", s->roll);
    return;
}
LPs
  • 16,045
  • 8
  • 30
  • 61
Jagadish
  • 9
  • 1

3 Answers3

4

At the top of your main function you declared db1 as:

struct db *db1;

It is a not initialized pointer, so you must allocate memory for the pointed struct db before dereference to its members:

db1 = malloc(sizeof(struct db));
if (db1 != NULL)
{
   db1->s1 = malloc(sizeof(struct student));
}

Moreover take notes that malloc & co. can fail: always check thier returned value

Lastly you are trying to allocate space for st1 in db1 struct, but just after that you are overwriting (memory leak) the pointer using:

db1->s1 = student1;
LPs
  • 16,045
  • 8
  • 30
  • 61
4

Your code is inconsistent. See for yourself.

In first case, you did

student1 = (struct student *)malloc(sizeof(struct student));

 /* Considering malloc success, 'student' points to valid memory */

student1->username = name;    //
student1->id = id;            //all the access are OK
student1->roll = roll;        //

but later, you did

db1->s1 = (struct student *)malloc(sizeof(struct student));  
db1->s1 = student1;

/* Wait, how do you know 'db' points to anything valid, at all? */

without allocating proper memory for db.

That said, if you're going to assign another pointer to a pointer, you don't need to reserve memory for the destination pointer. You're just making the pointer to point to something already valid (depending on the "validity" of the source pointer).

In case you're trying to use the memory location directly (read to or write from) pointed to by any pointer (example, destination of strcpy()) without any prior assigment, then you need to allocate memory first.

Obligatory suggestions:

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
-1

You need to allocate memory for db1 (through malloc) first, then its elements.

Jonas
  • 6,915
  • 8
  • 35
  • 53
Pras
  • 4,047
  • 10
  • 20