【问题标题】:C: Invalid read of size 1 & Address is 0 bytes after a block size 118 alloc'dC: 大小为 1 的无效读取 & 地址在块大小为 118 分配后为 0 字节
【发布时间】:2015-03-17 13:56:59
【问题描述】:

我需要一些帮助,因为我的代码在 valgrind 中引发了一些错误。代码虽然有效......所以我不明白问题是什么,你们能帮我看看吗?谢谢!

使用编译行:gcc -Wall -pedantic -ansi -g

char* readfile(char *filename) {
    FILE *fp;
    int size = 0;
    char *buffer = NULL;

    fp = fopen(filename, "r");
    if(fp != NULL) {
        /* Grab the size of the file */
        fseek(fp, 0L, SEEK_END);
        size = ftell(fp);
        fseek(fp, 0L, SEEK_SET);

        /* Memory allocate char */
        buffer = (char*) malloc(size);
        if(buffer == NULL) {
            printf("ERROR: Memory allocation error!\n");
            exit(EXIT_FAILURE);
        }

        /* Read the file and close */
        fread(buffer, size, 1, fp);
        fclose(fp);
    } else {
        printf("Failed to open %s file\n", filename);
    }

    return buffer;
}

int main(int argc, char * argv[]) {
    struct ets ets;
    struct menu_item menu_items[NUM_MENU_ITEMS];
    char *filebuffer = 0;

    /*if(argc != 4) {
        perror("Inputs are not valid\n");
        return EXIT_FAILURE;
    }*/

    filebuffer = readfile(argv[1]);

    printf("Contents: %s\n", filebuffer);
    free(filebuffer);

    return 0;
}

administrator:Assignment 2 Administrator$ valgrind --leak-check=full ./main equip.dat
==3972== Memcheck, a memory error detector
==3972== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3972== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3972== Command: ./main equip.dat
==3972== 
==3972== Invalid read of size 1
==3972==    at 0x828A: strlen (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==3972==    by 0x14BA8C: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==3972==    by 0x14A35E: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==3972==    by 0x14273F: printf (in /usr/lib/system/libsystem_c.dylib)
==3972==    by 0x100000BF1: main (ets_main.c:59)
==3972==  Address 0x10001c196 is 0 bytes after a block of size 118 alloc'd
==3972==    at 0x6B1B: malloc (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==3972==    by 0x100000B19: readfile (ets_main.c:31)
==3972==    by 0x100000BDB: main (ets_main.c:57)
==3972== 

【问题讨论】:

  • 与您的问题无关:不要在 c 中强制转换 malloc。
  • 为什么?我正在将其作为一门课程学习,他们告诉我们建议进行投射,因为它向读者展示了有用的信息。
  • 它向读者展示了不必要的混淆代码阅读here
  • 啊,好的,谢谢。

标签: c malloc valgrind


【解决方案1】:

你不要空终止buffer,把malloc改成

buffer = malloc(1 + size);

然后在检查malloc 成功后将其添加到某处

buffer[size] = '\0';

当将返回的指针传递给printf() 时,它正在读取1 字节超过malloced 块,因此出现valgrind 错误。

【讨论】:

  • 对不起,贴出我测试的代码,实际上设置为1。
  • 谢谢,将 +1 添加到缓冲区并添加 \0 有效。赞赏
  • 所以OP的代码实际上有两个问题......不是;-)
  • 嘿,是的。我之前已经对 malloc 做了 +1 并且没有任何区别,似乎它确实需要空终止符。谢谢
  • @JohnnyDoey 您应该始终将nul 终止符添加到将用作字符串的手工填充数组中,因为在c 中字符串被定义为以'\0' 结尾的字节序列。
猜你喜欢
  • 2023-03-03
  • 2012-06-07
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2012-11-01
相关资源
最近更新 更多