I'm trying to read a set of strings into an array. Therefore, I'm using a double pointer. Furthermore, I'm reallocing space to increase the double pointer's size if needed. I maintain the size of the double pointer at all times. However I get a non deterministic segmentation fault. For some inputs, the following program works. For others it doesn't. I've been able to isolate a case for when segmentation fault occurs but can't identify why I'm running into this fault:
// Maximum size of commands
#define MAX_COMMAND_LEN 30
// Initial size of instructions array
#define INIT_ARGS_SIZE 3
// Size
#define REALLOC_MARGIN 10
// Function prototypes
int getInput(char **instructionArray, int currentSize);
void freeDoubleArray(int size, char **array);
int main(int argc, char **argv) {
char **instructions;
instructions = (char**)calloc(INIT_ARGS_SIZE, sizeof(char*));
int count = getInput(instructions, INIT_ARGS_SIZE);
printf("\n Lets try the first string: %s\n", instructions[0]);
// Print all strings in array of strings
for (int i = 0; i < count; i++) {
printf("String '%d' is '%s' for count %d\n", i, instructions[i], count);
fflush(stdout);
}
freeDoubleArray(count, instructions);
return (0);
}
/**
* @brief Get instruction inputs from stdin
*
* @param instructionArray - double pointer to read instruction strings into
* @return int - return number of string sread in
*/
int getInput(char **instructionArray, int currentSize) {
int i = 0;
char temp[MAX_COMMAND_LEN];
while (fgets(temp, MAX_COMMAND_LEN, stdin) != NULL) {
if (i >= currentSize - 1) {
currentSize += REALLOC_MARGIN;
instructionArray = (char **)realloc(instructionArray, currentSize * sizeof(char*));
}
// Initialize string at this index
instructionArray[i] = (char*)calloc(strlen(temp) + 1, sizeof(char));
// Copy string read in into instruction array at index
strcpy(instructionArray[i], temp);
// Length of string read in
int length = strlen(instructionArray[i]);
// Ignore all lines with a single white space (or single character)
if (length <= 2) {
fprintf(stderr, "Warning - Line %d is empty.\n", i);
continue;
}
// Remove new line from the end of string
// Special case for windows
if (instructionArray[i][length - 1] == '\n' && instructionArray[i][length - 2] == '\r') {
instructionArray[i][length - 1] = '\0';
instructionArray[i][length - 1] = '\0';
}
// For all other OS
else
if (instructionArray[i][length - 1] == '\n')
instructionArray[i][length - 1] = '\0';
// Test output - ensure data is being written and accessible
printf("String '%d' is '%s' for i %d\n", i, instructionArray[i], i);
i++;
}
return (i);
}
/**
* @brief Free double char pointer
*
* @param size - size of double pointer
* @param array - double char pointer
*/
void freeDoubleArray(int size, char **array) {
// Loop through and free all indeces
for (int i = 0; i < size; i++)
free(array[i]);
// Free top level pointer
free(array);
}
Here's the case which gives me a segmentation fault:
asdasldlaksdj aklsdfjkl
askdlfjsalkdf sdfasd
sdflksjd fsa
dfajslkdfj salkdjf as
dfjksladjf s adf
a sdflkjsa dflaskdjf
asjdkfjas dklfjaslkd f
asdflksjdf as
dfsdkfjalskdf
sadfjksadjf sd
fsdjfkljasdf asdfjksd
asdjfklsja df
asdjflk sdf
asdjdfkl sjdfsdf
asdlkfj skdfj a
sdjfklsaj df
asdf sjakldfj
asdjfkasjlfjsald
asdflkjsdf asldkjf
askldfjas ldflk
Here's the console output:
./a.out < test
String '0' is 'asdasldlaksdj aklsdfjkl' for i 0
String '1' is 'askdlfjsalkdf sdfasd' for i 1
String '2' is 'sdflksjd fsa' for i 2
String '3' is 'dfajslkdfj salkdjf as' for i 3
String '4' is 'dfjksladjf s adf' for i 4
String '5' is 'a sdflkjsa dflaskdjf ' for i 5
String '6' is 'asjdkfjas dklfjaslkd f' for i 6
String '7' is 'asdflksjdf as' for i 7
String '8' is 'dfsdkfjalskdf ' for i 8
String '9' is 'sadfjksadjf sd' for i 9
String '10' is 'fsdjfkljasdf asdfjksd ' for i 10
String '11' is 'asdjfklsja df' for i 11
String '12' is 'asdjflk sdf' for i 12
String '13' is 'asdjdfkl sjdfsdf' for i 13
String '14' is 'asdlkfj skdfj a' for i 14
String '15' is 'sdjfklsaj df' for i 15
String '16' is 'asdf sjakldfj ' for i 16
String '17' is 'asdjfkasjlfjsald ' for i 17
String '18' is 'asdflkjsdf asldkjf ' for i 18
String '19' is 'askldfjas ldflk' for i 19
[1] 58751 segmentation fault ./a.out < test
Any input is appreciated!