Search code examples
cmallocdynamic-memory-allocation

cannot access malloc'ed memory beyond first address


Reading in a file, memory is dynamically allocated for a string where the file contents will be put. This is done inside of a function, the string is passed as char **str.

Using gdb I find that a seg fault is produced at the line **(str+i) = fgetc(aFile);

Here is the output of $ gdb a.out core along with the values of some variables:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000400bd3 in readFile (aFile=0x994010, str=0x7ffd8b1a9338) at src/morse.c:59
59      **(str + i) = fgetc(aFile);
(gdb) print i
$1 = 1
(gdb) print **(str + 0)
$2 = 65 'A'
(gdb) print *(str + 0)
$3 = 0x994250 "A"
(gdb) print (str + 0)
$4 = (char **) 0x7ffd8b1a9338
(gdb) print **(str + 1)
Cannot access memory at address 0x0
(gdb) print *(str + 1)
$5 = 0x0
(gdb) print (str + 1)
$6 = (char **) 0x7ffd8b1a9340

Here is the relevant function:

int readFile(FILE *aFile, char **str) // puts a file into a string
{
  int fileSize = 0;
  int i = 0;

  // count the length of the file string
  while(fgetc(aFile) != EOF)
    fileSize++;

  // malloc enough space for the string
  *str = (char *)malloc(sizeof(char) * (fileSize + 1 + 1)); // one for null, one for extra space
  if(!(*(str)))
    printf("ERROR: *str == NULL\n");

  // rewind() to the start of the file
  rewind(aFile);

  // put the file into a string
  for(i = 0; i < fileSize; i++)
    **(str + i) = fgetc(aFile);
  **(str + i - 1) = '\0';

  return 0;
}

Why is it that it's possible to access the beginning of the memory (for lack of a better term) but not more? What is the difference between the seemingly contiguous memory at the ** level and the non-contiguous memory at the * level?

The rest of the code can be seen on GitHub here.


Solution

  • It should be *(*str+i) instead of **(str+i). You have allocated memory to *str pointer.