在fscanf上读取大小4无效

时间:2015-02-11 21:37:58

标签: 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);
}

1 个答案:

答案 0 :(得分:0)

您为countToUse整数分配空间

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

然后遍历numsInFile,然后检查或numIntegers,这是错误的,并且您没有检查第一个fscanf()或{{1}的返回值}}

以下不会让valgrind抱怨

malloc()

通过从/* 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的循环,当然有更好的方法,但我只是想指出你的代码出了什么问题。

这些提示可以帮助您提高技能,据我所知,这是很好的

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

    这种情况不太可能发生,但这并非不可能,所以检查是明智的。

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

  3. 使用NULL使用调试信息编译程序时没有优化,正如@JohnBollinger所指出的那样,它将帮助您了解问题的确切位置。

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

    valgrind

    在调试时,这是一种防止愚蠢错误的绝佳方法,如果您关心可移植性,还可以添加gcc -Wall -Wextra -Werror -O0 -g3 ,如果您真的想要净化代码,还可以添加std=c99