fscanf 上的大小 4 读取无效
Invalid read of size 4 on fscanf
运行 我的程序通过 valgrind,我在以下代码中收到大小 4 错误的无效读取(我认为在调用 fscanf 的那一行)
重要信息:numIntegers
是可以读取的最大整数数量,而 numsInFile
指定文件中存在的整数数量。
我用两者中的最小值来初始化数组。这样做的原因是因为如果 numIntegers
是 100
并且文件中有 22
个整数,我只想要一个大小为 22
的数组。如果 numIntegers 是 22
并且文件中有 100
个整数,我仍然想要一个大小为 22
的数组,因为只能读取 22
。
这是我的代码:
// Get number of integers (first number)
int numsInFile;
fscanf(fp, "%d", &numsInFile);
// find minimum of numstoread and numintegers and use that as counttouse
if(numsInFile < numIntegers)
countToUse = numsInFile;
else
countToUse = numIntegers;
// Initialize the integers array with the minimum value as well - since it will only store this many
integers = malloc(sizeof(int) * countToUse);
for(int i = 0; i < numsInFile; i++){
if(i < numIntegers){
int currInt;
if(fscanf(fp, "%d", &currInt) == 1)
integers[i] = currInt;
else
break;
}
else
break;
}
提前感谢任何帮助。我这辈子都想不通为什么我在 valgrind 中遇到这个错误...
代码已编辑 - 不再有错误
// Get number of integers (first number)
int numsInFile;
if( fscanf(fp, "%d", &numsInFile) != 1)
fprintf(stderr, "Error reading number of integers(first number) from file. Exiting.\n");
exit(1);
}
// find minimum of numstoread and numintegers and use that as counttouse
if(numsInFile < numIntegers)
countToUse = numsInFile;
else
countToUse = numIntegers;
// Initialize the integers array with the minimum value as well - since it will only store this many
integers = malloc(sizeof(int) * countToUse);
for(int i = 0; i < countToUse; i++){
int currInt;
if(fscanf(fp, "%d", &currInt) == 1)
integers[i] = currInt;
else{
fprintf(stderr, "Error loading integer array in countAndSort(). Exiting.\n");
exit(1);
}
您为 countToUse
个整数分配了 space
integers = (int*)malloc(sizeof(int) * countToUse);
然后遍历numsInFile
,然后检查ornumIntegers
,这是错误的,你不检查第一个fscanf()
的return值或者你的 malloc()
.
下面不会让valgrind报错
/* Get number of integers (first number) */
int numsInFile;
if (fscanf(fp, "%d", &numsInFile) != 1)
doSomethingAboutIt_ButDoNotContinue();
/* find minimum of numstoread and numintegers and use that as counttouse */
if (numsInFile < numIntegers)
countToUse = numsInFile;
else
countToUse = numIntegers;
/*
* Initialize the integers array with the minimum value as well
* since it will only store this many
*/
integers = malloc(sizeof(int) * countToUse);
if (integers == NULL)
doSomethingAboutIt_ButDoNotContinue();
for (int i = 0 ; i < numsInFile ; i++)
{
if (i < countToUse) /* You allocated enough space for countToUse int's */
{
int currInt;
if (fscanf(fp, "%d", &currInt) == 1)
integers[i] = currInt;
else
break;
}
else
break;
}
当然有更好的方法,从 0
到 countToUse
循环,但我只是想指出您的代码有什么问题。
这些技巧应该可以帮助您提高技能,据我所知,这些技巧很好
始终检查函数中的 returned 值是否有错误,例如 malloc()
returns NULL
失败,而你没有不检查它。
这种情况发生的可能性很小,但并非不可能,所以检查一下是明智的。
使用编译器警告,它们可以帮助您解决那些通常难以发现的小错误。
当使用 valgrind
编译你的程序时,使用调试信息而不进行优化,正如@JohnBollinger 指出的那样,这将帮助你知道问题出在哪一行。
这是我使用的典型编译器命令
gcc -Wall -Wextra -Werror -O0 -g3
调试时它是防止愚蠢错误的极好方法,如果您关心可移植性,也可以添加 std=c99
,如果您真的想净化代码,也可以添加 -pedantic
。
运行 我的程序通过 valgrind,我在以下代码中收到大小 4 错误的无效读取(我认为在调用 fscanf 的那一行)
重要信息:numIntegers
是可以读取的最大整数数量,而 numsInFile
指定文件中存在的整数数量。
我用两者中的最小值来初始化数组。这样做的原因是因为如果 numIntegers
是 100
并且文件中有 22
个整数,我只想要一个大小为 22
的数组。如果 numIntegers 是 22
并且文件中有 100
个整数,我仍然想要一个大小为 22
的数组,因为只能读取 22
。
这是我的代码:
// Get number of integers (first number)
int numsInFile;
fscanf(fp, "%d", &numsInFile);
// find minimum of numstoread and numintegers and use that as counttouse
if(numsInFile < numIntegers)
countToUse = numsInFile;
else
countToUse = numIntegers;
// Initialize the integers array with the minimum value as well - since it will only store this many
integers = malloc(sizeof(int) * countToUse);
for(int i = 0; i < numsInFile; i++){
if(i < numIntegers){
int currInt;
if(fscanf(fp, "%d", &currInt) == 1)
integers[i] = currInt;
else
break;
}
else
break;
}
提前感谢任何帮助。我这辈子都想不通为什么我在 valgrind 中遇到这个错误...
代码已编辑 - 不再有错误
// Get number of integers (first number)
int numsInFile;
if( fscanf(fp, "%d", &numsInFile) != 1)
fprintf(stderr, "Error reading number of integers(first number) from file. Exiting.\n");
exit(1);
}
// find minimum of numstoread and numintegers and use that as counttouse
if(numsInFile < numIntegers)
countToUse = numsInFile;
else
countToUse = numIntegers;
// Initialize the integers array with the minimum value as well - since it will only store this many
integers = malloc(sizeof(int) * countToUse);
for(int i = 0; i < countToUse; i++){
int currInt;
if(fscanf(fp, "%d", &currInt) == 1)
integers[i] = currInt;
else{
fprintf(stderr, "Error loading integer array in countAndSort(). Exiting.\n");
exit(1);
}
您为 countToUse
个整数分配了 space
integers = (int*)malloc(sizeof(int) * countToUse);
然后遍历numsInFile
,然后检查ornumIntegers
,这是错误的,你不检查第一个fscanf()
的return值或者你的 malloc()
.
下面不会让valgrind报错
/* Get number of integers (first number) */
int numsInFile;
if (fscanf(fp, "%d", &numsInFile) != 1)
doSomethingAboutIt_ButDoNotContinue();
/* find minimum of numstoread and numintegers and use that as counttouse */
if (numsInFile < numIntegers)
countToUse = numsInFile;
else
countToUse = numIntegers;
/*
* Initialize the integers array with the minimum value as well
* since it will only store this many
*/
integers = malloc(sizeof(int) * countToUse);
if (integers == NULL)
doSomethingAboutIt_ButDoNotContinue();
for (int i = 0 ; i < numsInFile ; i++)
{
if (i < countToUse) /* You allocated enough space for countToUse int's */
{
int currInt;
if (fscanf(fp, "%d", &currInt) == 1)
integers[i] = currInt;
else
break;
}
else
break;
}
当然有更好的方法,从 0
到 countToUse
循环,但我只是想指出您的代码有什么问题。
这些技巧应该可以帮助您提高技能,据我所知,这些技巧很好
始终检查函数中的 returned 值是否有错误,例如
malloc()
returnsNULL
失败,而你没有不检查它。这种情况发生的可能性很小,但并非不可能,所以检查一下是明智的。
使用编译器警告,它们可以帮助您解决那些通常难以发现的小错误。
当使用
valgrind
编译你的程序时,使用调试信息而不进行优化,正如@JohnBollinger 指出的那样,这将帮助你知道问题出在哪一行。这是我使用的典型编译器命令
gcc -Wall -Wextra -Werror -O0 -g3
调试时它是防止愚蠢错误的极好方法,如果您关心可移植性,也可以添加
std=c99
,如果您真的想净化代码,也可以添加-pedantic
。