I have some code which takes a file, reads each line into a new string array (and adds 128 to each character), then assigns each array into an array of pointers, then prints each array. When trying to run the code I get an error stating a segmentation fault due to:
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: No such file or directory.
But I never actually call strlen inside my code?
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#define ROW 10
#define COL 40
#define ARGS 2
#define FLIP_VALUE 128
char** read_file (char* argv[], char **array_pointers);
char* new_array (void);
void print_strings (char** array_pointers);
int main(int argc, char* argv[])
{
char **array_pointers = NULL;
if (argc == ARGS)
{
array_pointers = read_file(&argv[1], array_pointers);
print_strings(array_pointers);
}
return 0;
}
char** read_file (char* argv[], char **array_pointers)
{
FILE* file_name;
int i = 0, j = 0;
char c;
char *temp_array;
array_pointers = malloc(sizeof(char*) * ROW);
file_name = fopen(argv[0], "r");
assert(file_name);
if (file_name) /* if file is not null */
{
while (c != EOF) /* while not equal to end of file */
{
for (j = 0; j < ROW; j++) /* for each row */
{
temp_array = new_array(); /* generate a new array for each new string (row) */
for (i = 0; i < COL; i++) /* for each char in a row */
{
c = fgetc(file_name);
temp_array[i] = c + FLIP_VALUE;
}
array_pointers[j] = temp_array; /*assign array pointers to point at each new temp_array */
}
}
}
return array_pointers;
}
char* new_array (void)
{
char* temp;
temp = malloc(sizeof(char) * COL);
assert(temp);
return temp;
}
void print_strings (char** array_pointers)
{
int i = 0;
for (i = 0; i < COL; i++)
{
printf("%s\n",array_pointers[i]);
}
}
The full stack trace reads as:
#1 0x00007ffff7a84e3c in _IO_puts (str=0x0) at ioputs.c:36
result = -1
len = <optimised out>
#2 0x0000000000400806 in print_strings (array_pointers=0x602010)
at array_of_string_arrays.c:65
i = 10
#3 0x00000000004006a1 in main (argc=2, argv=0x7fffffffdff8)
at array_of_string_arrays.c:19
array_pointers = 0x602010
There are actually several bugs here:
In read_file
, c
is initially undefined when first compared to EOF
. Do you even need this outer loop?
You should check the result of fgetc
as soon as it returns to see if it's EOF
.
You are allocating a new temp_array
for each character of each row, rather than once for each row. This needs to be moved up into the containing loop.
In print_strings
, you are iterating over the rows so you should compare the loop index to ROW
, not COL
.
When printing a row, you are using %s
in a printf
. You can't do that, since there is no guarantee that the characters in a row are null-terminated. You could force them to be, by allocating an additional character and storing '\0'
in it, or you could include a length field in the format specifier to limit the length (you can use *
to pass it as an argument).
I suspect the last bug is the one that's causing the segmentation fault.