I’m having trouble catching what I’m doing wrong inserting strings into an array in C. Below is the code. The printf lines show me that I am indeed reading the correct data — but after I stick each line of data into an array — I then inspect it to find that every element of the array is filled with the last line put into the array.
//Code snippet
char outbuf[BUFFER_LEN];
int std_out_count = 0;
char *std_out_lines[BUFFER_LEN]; /* Array to hold STDOUT */
while ((i = read(stdout_pipe_fds[0], outbuf, BUFFER_LEN - 1)) > 0) {
outbuf[i] = '\0';
char temp[BUFFER_LEN];
printf("PARENT read from stdout: %s\n", outbuf);
strcpy(temp, outbuf);
std_out_lines[std_out_count] = temp;
std_out_count++;
}
printf("STDOUT_COUNT: %i\n", std_out_count); /* Print out elements of array to make sure they're correct */
int idx;
for(idx = 0; idx < std_out_count; idx++) {
printf("STDOUT[%i]: %s\n", idx, std_out_lines[idx]);
}
// I can see by this output that I’m reading the correct values
/*
PARENT read from stdout: STDOUT = :this is line number 0:
PARENT read from stdout: STDOUT = :this is line number 1:
PARENT read from stdout: STDOUT = :this is line number 2: */
// But when I inspect the elements of the array — every element is filled with the last line read ;(
/*
STDOUT_COUNT: 3
STDOUT[0]: STDOUT = :this is line number 2:
STDOUT[1]: STDOUT = :this is line number 2:
STDOUT[2]: STDOUT = :this is line number 2: */
This line:
allocates an array of character pointers but does not allocate any space for the actual data itself.
Later on, when you do:
you’re actually overwriting the same piece of memory which each new line and storing its (unchanging) address into the next character pointer.
char temp[BUFFER_LEN];doesn’t give you a new data area every time it executes.That’s why it appears to be working. However, when
tempgoes out of scope, I wouldn’t suggest trying to examine any of the lines pointed at by your array. It’s undefined behaviour. It seems to be working for you but I’ll guarantee that’s purely by accident 🙂What you may want to look at is duplicating the string so that each array element has its own copy. Replace:
with:
or, just ditch
tempaltogether and use:This makes a copy of the string, and gives you the address of it for storing into the array, so that they’re all separate from each other. Just remember that you should probably free that memory eventually.
On the off-chance that your C implementation doesn’t have a
strdup(it’s not mandated by the ISO standard), here’s one I prepared earlier.