I have a problem with scanf() for string pointer as member of a struct.
#include <stdio.h>
#include <stdlib.h>
struct Student {
int studentNumber;
int phoneNumber;
char *studentName; //line 7
// char studentName[20]; //line 8
};
int main()
{
struct Student *list;
int numOfStudents;
int x;
int studentCounter = 1;
printf("\nEnter the number of students you would like to input: ");
scanf("%d", &numOfStudents);
list = malloc(sizeof(list) * numOfStudents); //line 21
for (x = 0; x < numOfStudents; x++) {
printf("\nEnter name for student #%d: ", studentCounter);
scanf("%s", list[x].studentName); //line 25
printf("Enter student number for student #%d: ",
studentCounter);
scanf("%d", &list[x].studentNumber); //line 27
printf("Enter phone number for student #%d: ",
studentCounter);
scanf("%d", &list[x].phoneNumber); //line 29
studentCounter++;
}
for (x = 0; x < numOfStudents; x++) {
printf("%s, #%d, %d: \n", list[x].studentName, list[x].studentNumber, list[x].phoneNumber);
}
return 0;
}
No error/warning to compile, but just did not work with "Segment fault!" error.
I believe the problem is with Line 7 and Line 25. If Line 8 is used, everything is fine. I am aware Line 7 does not allocate any memory for studentName, but Line 8 does. How do I solve this problem? Googled for a while, seems a common problem, but I'm still unclear with the right solution. Can anyone please explain it? Thanks a lot!
char *studentName; is a pointer to a string. What does it point to? Absolutely nothing and nowhere in particular. It might point to invalid memory and crash immediately. It might point to somewhere in your own stack frame, causing it to crash later in fascinating nondeterministic ways.
The correct solution would be to either
1) Use line 8
2) Point it to valid memory with a line like list[x].studentName=malloc(20);
I had thought Line 21 covers the allocation of studentName.
list[x].studentName=malloc(20);
I tried putting this line after Line 25, compiled fine, but did not work. Segment fault! again.
I am trying to use pointer. Where should I put this line for the correct way, not only to make the program run?
Thanks a lot again.
Thanks Carlo! It worked out very well! How stupid I was to put that after Line 25!!!
One more question about free(list[x].studentName). As this variable is within the loop for memory allcation, and will be used for later print. How do I free it in this case? I am confused because of the loop and as member of the struct, which is a array pointer. Handling malloc() is my worst part with C!
Thank you again!
Right now you're not freeing anything, which is... kind of okay... the same way its okay, if sloppy, to not close open files. It all goes away when the program ends anyway. But if you were doing that 10,000 times in a loop you'd be using 10,000 times as much memory which could definitely be a Bad Thing.
How to free it? As soon as you don't need any of that array anymore, do this:
for (x = 0; x < numOfStudents; x++) { free(list[x].studentName); }
free(list);
To fully understand what is happening here, I tried two ways to free the memory. One is within the printf() loop I freed list[x].studentName at Line 35. My understanding is: Once it has been printed, no needed any more and, free it. Then Line 38 free(list) for the struct;
The other is by putting a separate loop Line 37 to free(list[x].studentName). Then the same Line 38 free(list) as list is the struct;
Both had the same problem. Not sure Line 35 is a correct way.
Is Line 35 a correct way to do it?
Is Line 37 the only way to do it when handling 10~100 millions rows?
But both had error. What did I miss? Thanks a lot!
Remember from your other thread, what you get when you do sizeof(pointer) ? It takes you completely literally and gives you the size of the pointer. Which means you only allocate 4 or 8 bytes for the size of each index, and end up going way beyond the end when you loop.
That was really subtle and, fundamental, too. I can't get it until you pointed out!
This bugged me sooooo much, and I had thought my understanding is totally wrong. Fortunately I am on the right track, not that far away from right, at least.
Thank you very much again!