c - 将字符附加到 C 字符串时,Valgrind 无效读/写

标签 c gdb valgrind

我正在尝试解析一个字符串(大小从一篇文章到一整本书),并构建一个临时链表来存储每个单独的单词,由任何空白字符分隔。我自己写了charAppend()功能,因为我认为我不能使用 strcat()并传入 char* strchar c作为参数。最终我的目标是将这个单词链表组织成一个哈希表,当我试图以<word>:<number of occurrences>的格式输出哈希表内容时。与 printf我遇到了段错误。 printf 的参数在 gdb 上似乎没问题,但是当我运行 valgrind 时,我得到了很多 Invalid write of size 1Invalid read of size 1在我的 charAppend()功能。我不明白这里发生了什么,因为逐步使用 gdb 并没有给我太多信息。

我的 charAppend()功能:

//str is my current word, and c is the character I'm trying to append 
char* charAppend(char* str, char c) { 
    int length = 0;
    if (str != NULL) {
        length = strlen(str);
        str[length] = c;
        str = realloc(str, length+1);
        str[length+1] = '\0';
    }
    else {
        str = malloc(2); //1 for c, 1 for \0
        str[0] = c;
        str[1] = '\0';
    }
    return str;
}

下面是一些错误信息:

第 191 行是 str[length+1] = '\0';

% valgrind --leak-check=full --track-origins=yes test_wc wc-small.txt
==21794== Memcheck, a memory error detector
==21794== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21794== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==21794== Command: test_wc wc-small.txt
==21794== 
==21794== Invalid write of size 1
==21794==    at 0x109528: charAppend (wc.c:191)
==21794==    by 0x108EB5: wc_init (wc.c:47)
==21794==    by 0x108DAB: main (test_wc.c:47)
==21794==  Address 0x54db1e2 is 0 bytes after a block of size 2 alloc'd
==21794==    at 0x4C2DDCF: realloc (vg_replace_malloc.c:785)
==21794==    by 0x109513: charAppend (wc.c:190)
==21794==    by 0x108EB5: wc_init (wc.c:47)
==21794==    by 0x108DAB: main (test_wc.c:47)
==21794== 
==21794== Invalid read of size 1
==21794==    at 0x4C2EDB4: strlen (vg_replace_strmem.c:454)
==21794==    by 0x1094E5: charAppend (wc.c:188)
==21794==    by 0x108EB5: wc_init (wc.c:47)
==21794==    by 0x108DAB: main (test_wc.c:47)
==21794==  Address 0x54db1e2 is 0 bytes after a block of size 2 alloc'd
==21794==    at 0x4C2DDCF: realloc (vg_replace_malloc.c:785)
==21794==    by 0x109513: charAppend (wc.c:190)
==21794==    by 0x108EB5: wc_init (wc.c:47)
==21794==    by 0x108DAB: main (test_wc.c:47)

至少还有 10 条这样的错误信息,一些 Conditional jump or move depends on uninitialised value(s)作为第 190 行的结果,str = realloc(str, length+1);当我尝试打印哈希表内容时,有一些可能是这些的结果,我什至不明白。

==21794== Invalid read of size 8
==21794==    at 0x1092CE: wc_output (wc.c:124)
==21794==    by 0x108DD1: main (test_wc.c:51)
==21794==  Address 0xffefffe20 is on thread 1's stack
==21794==  1680 bytes below stack pointer
==21794== 
==21794== Invalid read of size 8
==21794==    at 0x1092EA: wc_output (wc.c:125)
==21794==    by 0x108DD1: main (test_wc.c:51)
==21794==  Address 0xffefffe20 is on thread 1's stack
==21794==  1680 bytes below stack pointer

我的猜测是我对 C 字符串(尤其是修改它们)的工作方式没有正确的理解(自从我参加入门级别的 C 类(class)以来已经有 2 年了),但是对于发生了什么或可能是什么错误的任何帮助,以及有关如何调试这些的建议,我们将不胜感激!

如果有帮助,我可以发布更多代码,但我认为 charAppend()是主要嫌疑人。

最佳答案

这部分有多个错误:

    length = strlen(str);
    str[length] = c;
    str = realloc(str, length+1);
    str[length+1] = '\0';

1) strlen 不会 为您提供分配的内存量。它给出的金额减去 1。这是因为 strlen 不包括字符串终止符。所以你的 realloc 是错误的。

2) 永远不要realloc 直接进入目标指针。 realloc 可能返回 NULL

所以试试:

    length = strlen(str);
    char * tmp = realloc(str, length+2); // note +2
    if (tmp == NULL) exit(1);            // bad error
    str = tmp;
    str[length] = c;
    str[length+1] = '\0';

关于c - 将字符附加到 C 字符串时,Valgrind 无效读/写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52448028/

相关文章:

C语言-凯撒加密程序

c++ - C++ eclipse 调试器出现以下错误。 'Launching program name' 遇到...启动命令 : gdb --version 时出错

c++ - 解构const指针?

c - 在 valgrind 上运行 DPDK 应用程序时出错

c - Valgrind:在 strcpy 上写入大小 1 无效

c - 从 create_proc_read_entry 迁移到 proc_create 并使用 seq_files

矩阵批量乘法的Cuda程序

c - 我应该为多个连接使用单独的 ODBC 环境吗?

c - gdb单步执行动态函数

c++ - GDB中基于局部变量存在性的流量控制