无法在第一个地址之外访问malloc的内存

时间:2015-04-18 19:32:27

标签: c malloc dynamic-memory-allocation

在文件中读取时,会为将放置文件内容的字符串动态分配内存。这是在函数内部完成的,字符串作为char **str传递。

使用gdb我发现在**(str+i) = fgetc(aFile);

处产生了一个seg错误

以下是$ gdb a.out core的输出以及一些变量的值:

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

以下是相关功能:

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;
}

为什么可以访问内存的开头(缺少更好的术语)但不是更多? **级看似连续的内存与*级别的非连续内存有什么区别?

其余代码可以在GitHub here上看到。

4 个答案:

答案 0 :(得分:7)

应该是*(*str+i)而不是**(str+i)。您已将内存分配给*str指针。

答案 1 :(得分:1)

在您的代码中,指向已分配内存块的指针为*str,而不是**str。因此,您希望设置*((*str) + i)或等效(*str)[i]的值。

答案 2 :(得分:0)

应该是*(* str + i),你应该被风格警察开除 首先使用这种编码风格。

使用像

这样的模式

char * myStr = * str =(char *)malloc ....

* myStr [i] = byte

...

答案 3 :(得分:0)

@ B. Shankar已经给了你答案,但我想我应该指出一些改变。

除非您需要使用指针算法,否则您的代码中绝对不需要所有循环,您可以像这样执行

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

  // count the length of the file string
  fseek(aFile, 0L, SEEK_END);
  fileSize = ftell(aFile);
  fseek(aFile, 0L, SEEK_SET);

  // malloc enough space for the string
  *str = malloc(fileSize + 1 + 1)); // one for null, one for extra space
  if (*str == NULL)
      return -1;    
  if (fread(*str, 1, fileSize, aFile) != fileSize)
      return -1;
  return 0;
}