【发布时间】:2014-08-29 00:01:31
【问题描述】:
C 和 Valgrind 以及手动内存管理的新手,我无法找到运行 Valgrind 时遇到的错误。我有这个从用户那里获取字符串的函数:
char **get_fragments_from_user(){
// No more than 20k strings containing at most 1k characters
char **strings = malloc(20000 * sizeof(char *));
char tempstring[MAX_INPUT]; //MAX_INPUT = 1001
int count = 0;
while(true){
printf("\n> ");
fgets(tempstring, MAX_INPUT, stdin);
if((strlen(tempstring) > 0) && (tempstring[strlen(tempstring) - 1] == '\n')){
tempstring[strlen(tempstring) - 1] = '\0';
}
if(tempstring[0] == 'q') break;
strings[count] = malloc(sizeof(char) * (strlen(tempstring)+1));
strcpy(strings[count], tempstring);
count++;
}
int i = 0;
char **fstrings = malloc((count)*sizeof(char *)); // count+1 needed? Something I tried removing while debugging
for(i = 0; i < count; i++){
fstrings[i] = malloc(sizeof(char) * (strlen(strings[i])+1));
strcpy(fstrings[i], strings[i]);
free(strings[i]);
}
free(strings);
return fstrings;
}
这里的想法只是获取字符串并将它们放入数组中。我最初分配了一个足够大的数组,以适应可以输入的最大字符串数(20,000),但我随后调整了数组的大小,以便分配的内存不会超过每个字符串所需的内存。我对上面的代码有点尴尬,因为它没有我用另一种语言编写的任何代码那么干净,但这是我第一次通过。
然后,当我尝试使用此函数计算数组中的字符串数时,我从 Valgrind 得到“大小为 8 的无效读取”:
int lengthOf(char **arr){
int i = 0;
while(arr[i] != NULL){
i++;
}
return i;
}
我很确定这是由于取消引用的指针或其他原因造成的,但我一生都找不到它,而且我一直在看这段代码一个小时左右。
【问题讨论】:
-
建议,
char **fstrings = calloc(count+1, sizeof(char *)); -
加号:
return fstrings;-->>fstrings[i] = NULL; -
好的,所以要 count+1 并将 malloc 变成 calloc 已经摆脱了我原来遇到的问题,但我现在遇到了一些其他问题,但我会看看我是否可以首先通过它们。另一个大小为 1 的无效读取。
-
@wildplasser:为什么要这样做?我的直觉是它确保 lengthOf 函数能够正常工作,但我不完全确定这是否正确。
-
lengthof() 函数计数,直到它在数组中看到 NULL。你没有在里面放一个 NULL,那为什么要放一个呢?
标签: c arrays memory memory-management valgrind