c - 大小 4 的无效读取,valgrind fscanf

标签 c

我正在做一项作业,但在调试时遇到了一个奇怪的问题。

==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

我一辈子都弄不明白为什么我会在 valgrind 中遇到这个错误。除此以外,代码有效。

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

#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
Nod1 Nod2

它编译正确并打印出 9。

使用这些设置编译:

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

使用这些设置在 valgrind 中运行:

valgrind --leak-check=yes --show-reachable=yes ./myProgram

谁能发现我做错了什么?

最佳答案

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

我将发布一些我认为非常健壮并且根本不会导致任何 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() 扫描最多 50 字节并为终止 null 字符留出空间。

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

相关文章:

c++ - c 或 c++ 中的并行矩阵求逆

c - AES-CBC + HMAC 和 AES-GCM 之间的极端时间差异

c - 滑动拼图应用程序,DFS

c - gcc 编译 c++ 时不带任何标志

c - 想要检查文件中是否存在值

c - 从 gcc 中的内联汇编引用全局变量

c - 如何在 C 中存储字节数组?

c - 结构赋值是否保证填充也相等

使用不同的CFLAGS为不同的目标编译通用的C文件

c# - 如何从 ORed 标志中检索返回值