c - fscanf 上大小 4 的读取无效

标签 c arrays valgrind dynamic-arrays scanf

通过 valgrind 运行我的程序,我在以下代码中遇到了“无效读取大小 4”错误(我认为是在调用 fscanf 的行)

重要信息:numIntegers是可以读取的最大整数个数,而 numsInFile指定文件中存在的整数数量。

我使用两者中的最小值来初始化数组。这样做的原因是因为如果 numIntegers100还有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 个整数分配空间

integers = (int*)malloc(sizeof(int) * countToUse);

然后迭代numsInFile,然后检查或numIntegers,这是错误的,并且您没有检查第一个fscanf(的返回值)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;
}

当然有更好的方法来做到这一点,通过从 0countToUse 循环,但我只是想指出你的代码出了什么问题.

这些技巧应该可以帮助您提高技能,据我所知,这些技巧很好

  1. 始终检查函数返回的值是否有错误,例如 malloc() 在失败时返回 NULL,而您没有检查它。

    这种情况发生的可能性很小,但也不是不可能,因此检查一下是明智的。

  2. 使用编译器警告,它们可以帮助您解决那些通常很难看到的小错误。

  3. 当使用 valgrind 编译程序时,使用调试信息而不进行优化,正如 @JohnBollinger 所指出的,这将帮助您了解问题所在的确切行。

    这是我使用的典型编译器命令

    gcc -Wall -Wextra -Werror -O0 -g3
    

    在调试时,它是防止愚蠢错误的绝佳方法,如果您关心可移植性,您还可以添加 std=c99 ,如果您确实想净化您的代码,则可以添加 -pedantic代码。

关于c - fscanf 上大小 4 的读取无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28464994/

相关文章:

c - 尝试从结构中检索 U32 时程序崩溃

arrays - 根据计数进行逐元素数组复制

c++ - 内存泄漏和嵌入式 linux

c - 为什么这些函数名称要放在括号中?

c - 使用 system() 打开 2 个终端并选择默认输出

c++ - gcc 4.8.1 默认启用 sse 吗?

c++ - 如何使用 Valgrind 检测段错误细节?

php - [1] => 0 在这个数组中是什么意思?

javascript - AngularJS - 在数组中单步执行数组

c++ - Valgrind 对 FILE 的读取无效*