无法访问第一个地址以外的 malloc 内存
cannot access malloc'ed memory beyond first address
读入一个文件,内存是动态分配的,用于放置文件内容的字符串。这是在函数内部完成的,字符串作为 char **str
传递。
使用 gdb 我发现在行 **(str+i) = fgetc(aFile);
处产生了段错误
这是 $ 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
(gdb) print **(str + 0)
= 65 'A'
(gdb) print *(str + 0)
= 0x994250 "A"
(gdb) print (str + 0)
= (char **) 0x7ffd8b1a9338
(gdb) print **(str + 1)
Cannot access memory at address 0x0
(gdb) print *(str + 1)
= 0x0
(gdb) print (str + 1)
= (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) = '[=11=]';
return 0;
}
为什么可以访问内存的开头(因为缺少更好的术语)而不是更多?
**级看似连续的内存和*级不连续的内存有什么区别?
其余代码见GitHubhere.
应该是*(*str+i)
而不是**(str+i)
。您已将内存分配给 *str
指针。
在您的代码中,指向已分配内存块的指针是 *str
,而不是 **str
。因此,您想要设置 *((*str) + i)
的值,或者等效地设置 (*str)[i]
.
应该是 *(*str+i) ,你应该被风格警察枪杀
首先使用类似这种编码风格的东西。
使用像
这样的模式
char *myStr = *str = (char *) malloc ....
*myStr[i] = 字节
.....
@ 已经给了你答案,但我想我应该指出一些改进之处。
除非你需要用指针算法来完成,否则你的代码中绝对不需要所有的循环,你可以这样做
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;
}
读入一个文件,内存是动态分配的,用于放置文件内容的字符串。这是在函数内部完成的,字符串作为 char **str
传递。
使用 gdb 我发现在行 **(str+i) = fgetc(aFile);
这是 $ 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
(gdb) print **(str + 0)
= 65 'A'
(gdb) print *(str + 0)
= 0x994250 "A"
(gdb) print (str + 0)
= (char **) 0x7ffd8b1a9338
(gdb) print **(str + 1)
Cannot access memory at address 0x0
(gdb) print *(str + 1)
= 0x0
(gdb) print (str + 1)
= (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) = '[=11=]';
return 0;
}
为什么可以访问内存的开头(因为缺少更好的术语)而不是更多? **级看似连续的内存和*级不连续的内存有什么区别?
其余代码见GitHubhere.
应该是*(*str+i)
而不是**(str+i)
。您已将内存分配给 *str
指针。
在您的代码中,指向已分配内存块的指针是 *str
,而不是 **str
。因此,您想要设置 *((*str) + i)
的值,或者等效地设置 (*str)[i]
.
应该是 *(*str+i) ,你应该被风格警察枪杀 首先使用类似这种编码风格的东西。
使用像
这样的模式char *myStr = *str = (char *) malloc ....
*myStr[i] = 字节
.....
@
除非你需要用指针算法来完成,否则你的代码中绝对不需要所有的循环,你可以这样做
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;
}