Reputation: 573
I wrote a small program to illustrate a problem I'm running into. This program should copy the contents of "buff[200]" into the first position of the array "output". After performing the copy, I read the value out several times to see when it vanishes as I get a segmentation fault as soon as I try to access the data outside of the scope of driverFunc. I'm aware that I'm creating an array with 6 positions in it but only adding data to the first position, this will eventually be inside a loop that populates the rest of the output array. I also have the requirement for my use case that I need to be able to expand the size of this array.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 1035
int driverFunc(char ** output, int * sizeOfOutput) {
int rows = 5;
char buff[200] = "hello world";
output = malloc(rows * sizeof(char *)); //malloc row space
//malloc column space
for (int i = 0; i < rows; i ++) {
output[i] = malloc(BUFFER_SIZE * sizeof(char));
}
//copy contents of buff into first position of output
strncpy(output[0], buff, BUFFER_SIZE-1);
printf("Output 1: %s\n", output[0]); //verify that it's there
//resize the array
output = realloc(output, (rows+1) * sizeof(char *));
//allocate space for the new entry
output[rows] = malloc(BUFFER_SIZE * sizeof(char));
*sizeOfOutput = rows;
//verify that it's still there
printf("Output 2: %s\n", output[0]);
return 0;
}
int main() {
char ** outputs;
int sizeOfOutput;
driverFunc(outputs, &sizeOfOutput);
//verify that we can do useful things with our output
printf("Reported size: %d\n", sizeOfOutput);
printf("Captured output: %s\n", outputs[0]); //segfault
}
expected output:
Output 1: hello world
Output 2: hello world
Reported size: 5
Captured output: hello world
received output:
Output 1: hello world
Output 2: hello world
Reported size: 5
Segmentation fault (core dumped)
Upvotes: 1
Views: 479
Reputation: 310990
If you are going to change the value of the pointer outputs
declared in main
char ** outputs;
in a function then the function should except the pointer by reference that is indirectly through pointer.
Thus the function should be declared at least like
int driverFunc(char *** output, int * sizeOfOutput);
and called like
driverFunc( &outputs, &sizeOfOutput);
Using the function strncpy
strncpy(output[0], buff, BUFFER_SIZE-1);
does not make great sense. It is simpler to use strcpy
strcpy( output[0], buff );
In case if the reallocation fails
output = realloc(output, (rows+1) * sizeof(char *));
the previous value of the pointer output
will be lost. So you need to use an intermediate variable to reallocate the memory and check whether its value after the call is equal to NULL or not.
The variable sizeOfOutput
should be set to
*sizeOfOutput = rows + 1;
In main you should free all allocated memory in the function.
Upvotes: 1
Reputation: 18320
You are passing outputs
into driverFunc
as a value:
driverFunc(outputs, &sizeOfOutput);
its value will be passed to function but not returned. So, when you use it in:
printf("Captured output: %s\n", outputs[0]);
outputs
is still uninitialized.
You need to pass it as a reference (and change driverFunc
accordingly):
driverFunc(&outputs, &sizeOfOutput);
or just return it:
outputs = driverFunc(&sizeOfOutput);
Upvotes: 1