I’m trying to loop through the contents of a stream to dynamically generate nodes in a list, given the contents of each line that I read. I have a struct that I defined below:
struct info {
char *mystring;
char *file;
int line_no;
struct info *next;
};
I use this loop to iterate through the stream:
while(1) {
char t [KMAX];
char* file;
char* line_no;
char* text;
if (fgets(t, KMAX, file_pipe) != NULL) {
file = strtok (t, delimiter);
line_no = strtok(NULL, delimiter);
int line = atoi(line_no);
text = strtok(NULL, delimiter);
add(&head, text, line, file);
}
I know the variables are passed correctly to my add function, because I print them out each time and I can verify it. However, the problem comes when I try to print the list. It just prints the last line of text and file name, but the integer value changes accordingly. My guess is that it has something to do with the array being destoryed and being re-created each time in the same block of memory, so the pointers get changed each time.
I’m not sure what the proper method is to go about fixing this problem. Do I modify my while loop somehow and use char pointers in a difference manner, or should I change my struct somehow to hold the variables, instead of just using pointers? I would appreciate any feedback!
EDIT : Added more code
void add(struct info **x, char * text, int line_no, char * file) {
struct info* current = *x;
struct info* newInfo;
newInfo = malloc(sizeof(struct info));
(*newInfo).next = NULL;
(*newInfo).grepstring = text;
(*newInfo).line_no = line_no;
(*newInfo).file = file;
if (current == NULL) { //indicates the head is null, special case
*x = newInfo;
} else {
//get to the end of the list
while ((*current).next != NULL) {
current = (*current).next;
}
//apends node to the end of the list
(*current).next = newInfo;
}
}
When you say
char* text, what you are doing is allocating achar*on the stack.strtokisn’t pointing it to some newly allocated memory, it’s pointing it into the stack-allocated space oft.This memory is lost when it falls out of scope, which happens at the bottom of each iteration of the
whileloop. Any references to its address might point to the correct contents, or nothing, or some other random value after that point – the behavior they exhibit is undefined.You need the contents of each
struct infoto survive the loop (and, presumably, continue to survive for the foreseeable future). To do this you must make a heap allocation. In C this is done via themallocfunction.In your
addmethod, say:This will create new memory on the heap, having the same contents as the original text.
You should do this for all the contents of the
struct info, since at the moment they’re all pointers into the stack-allocatedtbuffer.You must
freethe memory again when you are done with it, but it will last until then.