1

I've created two structs:

typedef struct Student{
    int id; 
    char* name;
    int birthYear;
    int finishedCourses;
    int courseCredits;
    double avarage;
    int coursesNow;
    NodeCourses* courses;

}Student;

typedef struct NodeS{
    Student student;
    struct NodeS* next;
}NodeS;

So I can now create a linked list of students.

one of the things I want to do is to ask the user to put details about each student.

so Ive created a function that called "addNewStudent"

first in the function it does this:

NodeS* newStudent;
    newStudent=(NodeS*)malloc(sizeof(NodeS));

and than, when I am asking the user to insert a name I put it in a string called "name" and I want to malloc again the name string. so I do this:

newStudent->student.name=(char*)malloc(sizeof(char)*strlen(name));

and that line gives me segmentation fault.

ps: Ive checked the string is in the write size and that i get is correctly.

what should I do?

Juno
  • 81
  • 6
  • 1
    As a side note, refer to the top answer of this question: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Thomas Jager May 10 '19 at 16:19
  • 2
    Also, assuming that you're doing what it looks like you're doing, you want to allocate `sizeof(char) * (strlen(name) + 1)`, to have space for the null terminator. – Thomas Jager May 10 '19 at 16:21
  • 3
    If that line is giving you a fault, you must have done something earlier that cause undefined behavior, and it corrupted the heap. It could be because you're not adding 1 to the name length, so creating a previous student caused a buffer overflow. – Barmar May 10 '19 at 16:25
  • 1
    We'd need to see more of your program to tell what all your problems are. – Barmar May 10 '19 at 16:26
  • 1
    Please show how you `put it in a string called "name"` – Nick S May 10 '19 at 16:37
  • Yes, you need to post more code. C's segfault is not local and can be caused by something you didn't expected. Alternatively, you can do a self segfault diagnosis with my tool: https://segfault.stensal.com, Just copy & paste your code and run it. You should see the cause immediately. – stensal May 10 '19 at 16:48

1 Answers1

2
 newStudent->student.name=(char*)malloc(sizeof(char)*strlen(name));

I am taking you at your word that this exact line of code causes a segmentation fault. There are three things this line of code does, any one of which could be your cause:

1) You do strlen(name). If name does not point to a valid C-style string with a proper nul terminating byte, this could segfault. You can test this theory by adding this before the line of code:

printf("About to call strlen\n");
printf("Got: %d\n", strlen(name));

If this is the problem, you will see the first line of output but not the second since the segfault will terminate the program before it gets a chance to execute.

2) You call malloc. It's possible that the heap has become corrupt due to a previous double free, use after free, buffer overrun, or similar problem. So the call to malloc may be the victim of previous damage. You can test this by adding this code:

printf("About to call strlen\n");
printf("Got: %d\n", strlen(name));
printf("About to call malloc\n");
char *o = malloc(sizeof(char) * strlen(name));
printf("Malloc didn't segfault\n");
newStudent->student.name=o;

3) You assign to newStudent->student.name. If, for example, newStudent is NULL or otherwise doesn't point to valid contents, that could be your issue. You can test this by adding this code:

printf("About to call strlen\n");
printf("Got: %d\n", strlen(name));
printf("About to call malloc\n");
char *o = malloc(sizeof(char) * strlen(name));
printf("Malloc didn't segfault\n");
printf("Trying to access newStudent->student.name\n");
printf("newStudent->student.name=%p\n", newStudent->student.name);
newStudent->student.name=o;
printf("Actually, the whole statement worked\n");

If you see all the printfs but your program still crashes, then you were wrong about the statement causing the segfault.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • We can be reasonably certain that he copied the name into the buffer measured like this, and so trashed the heap. It's not unreasonable the crash comes back on the next invocation of the same faulty line. It was only a matter of time ... – Joshua May 10 '19 at 18:25