【发布时间】:2019-01-20 13:00:43
【问题描述】:
我在试图理解为什么 valgrind 告诉我我超出了 char *array 的范围时遇到了一些问题。
每当我尝试从 nul 字节之前开始向后迭代数组时。它向我抛出了我正在访问不应该访问的内存的错误。
这是我的第一个函数:
char *ReadLineFile(FILE *infile) {
int initSize = 16;
char *string = NULL;
string = malloc(sizeof(char) * initSize);
if(string == NULL){
exit(-1);
}
char val;
int valSize = 0;
while((val = fgetc(infile)) != EOF){
if(val == '\n'){
break;
}
if(valSize == initSize){
initSize *= 2;
string = realloc(string, initSize * sizeof(char));
}
string[valSize++] = val;
}
if(valSize == initSize){
initSize++;
string = realloc(string, initSize * sizeof(char));
}
string[valSize++] = '\0';
return trimString(string);
}
这是我的第二个功能:
char *trimString(char *string) {
int start = 0;
int end = strlen(string);
while(string[start] == ' '){start++;}
while(string[end-2] == ' '){end--;} // the [end-2] causes the error in valgrind
int trimLen = end - start;
char *trimmedStr = malloc(sizeof(char) * (trimLen + 1));
if(trimmedStr == NULL){
exit(-1);
}
int i = 0;
while(start != end){
trimmedStr[i] = string[start];
i++; start++;
}
trimmedStr[i] = '\0';
free(string);
return trimmedStr;
}
Valgrind 错误:
==3809== Invalid read of size 1
==3809== at 0x1090D5: trimString (myio.c:129)
==3809== by 0x109080: ReadLineFile(myio.c:120)
==3809== by 0x108C54: main (driver2.c:29)
==3809== Address 0x522e03e is 2 bytes before a block of size 16 alloc'd
==3809== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload/memcheck-amd64-linux.so)
==3809== by 0x108F91: ReadLineFile(myio.c:90)
==3809== by 0x108C54: main (driver2.c:29)
我希望 valgrind 不会出现错误,因为我在字符串中分配了足够的内存,而是告诉我,当我尝试向后迭代数组时,我正在尝试访问我不应该访问的内存。我想了解是什么原因造成的,因为我花了几个小时试图找出这个错误。谢谢!
【问题讨论】:
-
char val不能包含 EOF,因为 EOF 需要short或int... 使用int val来检测 EOF。 -
while(string[start] == ' '){start++;}可能超出字符串的末尾,使用while(start < end && string[start] == ' ') ++start;同样适用于while(string[end-2] == ' '){end--;},使用while(end > start && string[end-1] == ' '){end--;} -
终于!这解决了我的问题。在文件的末尾,有一个只包含一个空字节的空字符串,这导致数组超出范围。非常感谢你!也感谢您澄清 val 的数据类型!
-
我很高兴能帮上忙。随意投票/接受我的回答;-)
-
完成,非常感谢!