I have a struct defined as
typedef struct
{
char* name;
char* ID;
int marks;
char* details;
} Student;
And another as
typedef struct
{
int n;
Student* stud_array;
} Batch;
A file has entries of various batches of student in a particular format, and I’m reading from that file to populate BatchArray of type Batch*
After each field is populated I am using
puts(BatchArray[no_of_batches-1].stud_array[i].name);
puts(BatchArray[no_of_batches-1].stud_array[i].ID);
printf("%d\n",BatchArray[no_of_batches-1].stud_array[i].marks);
to see the result. And it gives me the right output.
However, after everything is done, when I want to iterate through BatchArray, only the marks field in each struct retains the value. The name and ID are shown to be some random garbage value.
The iteration code is standard. Nevertheless, here it is.
for(i = 0; i < no_of_batches; i++) {
currBSize = BatchArray[i].n;
printf("Batch %d\n", (i+1));
printf("Batch size %d\n", currBSize);
for(j = 0; j < currBSize; j++) {
puts(BatchArray[i].stud_array[j].name);
}
}
The problem that I’m working on needs to find the average marks of each batch, so that’s not a problem. But I’d like to know why the other fields get reset to garbage values.
Can someone help with this?
Edit : here is how I’m populating the fields.
The file consists of entries like this
3
Name1 ID1 marks1
Name2 ID2 marks2
Name3 ID3 marks3
2
Name4 ID4 marks4
Name5 ID5 marks5
and this is the code.
no_of_batches = 0;
infileptr = fopen (infilename, "r");
BatchArray = (Batch *) malloc(sizeof(no_of_batches));
int MAX_BUFF = 100;
char currLine[MAX_BUFF];
while (fgets(currLine, MAX_BUFF, infileptr) != NULL) {
no_of_batches++;
BatchArray = (Batch *) realloc(BatchArray, no_of_batches*sizeof(Batch));
currBatchSize = atoi(currLine);
BatchArray[no_of_batches-1].n = currBatchSize;
printf("currBatchSize : %d\n",BatchArray[no_of_batches-1].n);
BatchArray[no_of_batches-1].stud_array = (Student *) malloc(currBatchSize*sizeof(Student));
for(i = 0; i < currBatchSize; i++) {
fgets(currLine, MAX_BUFF, infileptr);
currLine[strlen(currLine)-1] = '\0';
BatchArray[no_of_batches-1].stud_array[i].details = currLine;
//getting the Name from currLine
j = 0;
len = strlen(currLine);
char buildName[len];
while(currLine[j] != ' ') {
buildName[j] = currLine[j];
j++;
}
buildName[j] = '\0';
BatchArray[no_of_batches-1].stud_array[i].name = buildName;
j++;
//getting the ID from currLine
k = 0;
char buildID[len];
while(currLine[j] != ' ') {
buildID[k] = currLine[j];
j++;
k++;
}
buildID[k] = '\0';
BatchArray[no_of_batches-1].stud_array[i].ID = buildID;
puts(BatchArray[no_of_batches-1].stud_array[i].name);
puts(BatchArray[no_of_batches-1].stud_array[i].ID);
//getting the marks from currLine
k = 0;
j++;
char buildMarks[len];
while(currLine[j] != '\0') {
buildMarks[k] = currLine[j];
j++;
k++;
}
buildMarks[k] = '\0';
BatchArray[no_of_batches-1].stud_array[i].marks = atoi(buildMarks);
printf("%d\n",BatchArray[no_of_batches-1].stud_array[i].marks);
}
puts("");
}
Instead of
write
The problem with the first case is that
namepoints tobuildName, which is an array on the stack and will be overwritten whenever the contents of the stack change.In the second case you’ve copied the array to newly allocated heap memory (as with
mallocorrealloc), which will remain unmodified until youfreeit.