无效读取大小4,valgrind fscanf

时间:2017-08-22 20:04:43

标签: c

我正在进行调试,但在调试时遇到了一个奇怪的问题。

process_big_object(p)

我不能为我的生活弄清楚为什么我在valgrind中得到这个错误。除此之外,代码可以正常工作。

我做了一个测试项目来隔离错误:

==30771== Invalid read of size 4
==30771==   at 0x4E9CC5D: __isoc99_fscanf (isoc99_fscanf.c:30)
==30771==   by 0x400728: main main.c:13)
==30771== Address 0x0 is not stack'd, malloc'd or (recently) free'd

该文件如下所示:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    FILE *myFile;
    myFile = fopen("../map1.map", "r");

    char *buff = malloc(51*sizeof(char));

    //Scanning for the amount of edges.
    if (fscanf(myFile, "%s", buff) != 1){
        printf("Something is wrong\n");
    }

    printf("%s", buff);

    fclose(myFile);

    char str[20];
    scanf("%s", str);
}

它正确编译并打印9。

使用以下设置进行编译:

9
Nod1 Nod2

使用以下设置在valgrind中运行:

gcc -g -std=c99 -Wall -Werror -O0 main.c -o myProgram

有人能发现我做错了吗?

1 个答案:

答案 0 :(得分:3)

未定义行为的概念,如果你不是很小心你可以触发这种未定义的行为然后,你将无法判断程序是否正常工作或不。

我会发布一些我认为非常健壮且不应该导致任何 valgrind 报告的代码,包括删除最后一个无效的语句,我改变的每件事都是可能是问题的原因

你必须在返回一个值时检查每个函数是否成功,你自己的程序的更强大的版本是

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    FILE *file;
    const char *filepath;
    char *buffer;

    filepath = "../map1.map";
    file = fopen(filepath, "r");
    if (file == NULL) {
        fprintf(stderr, "error openning: %s\n", filepath);
        return -1;
    }

    buffer = malloc(51);
    if (buffer == NULL) {
        fprintf(stderr, "error, memory exhausted\n");
        fclose(file);

        return -1;
    }


    // Scanning for the amount of edges.
    if (fscanf(file, "%s", buffer) != 1){
        fprintf(stderr, "error, cannot read from the file\n");
    } else {
        fprintf(stdout, "%s\n", buffer);
    }
    // Release all resources
    fclose(file);
    free(buffer);

    return 0;
}

如果使用 valgrind 运行此代码,则无论文件是否存在,都可能会报告 0 错误。但你必须小心,

fscanf(file, "%s", buffer)

因为它可以溢出buffer,所以请告诉fscanf()读取这样的给定字节数

fscanf(file, "%50s", buffer)

这样,让fscanf() scanf最多50个字节,并为终止null字符留出空间。