Valgrind 在将字符附加到 C 字符串时读/写无效



我正在尝试解析一个字符串(大小从一篇文章到整本书(,并建立一个临时链表来存储每个单独的单词,用任何空格字符分隔。我编写了自己的charAppend()函数,因为我认为我不能使用strcat()并将char* strchar c作为参数传递。最终,我的目标是将这个单词链表组织成一个哈希表,当我尝试以<word>:<number of occurrences>格式输出哈希表内容时,printf我遇到了一个 seg 错误。printf参数在 gdb 上似乎还可以,但是当我运行 valgrind 时,我的charAppend()函数中得到了很多Invalid write of size 1Invalid read of size 1。我不明白这里发生了什么,因为使用 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] = '';
}
else {
str = malloc(2); //1 for c, 1 for 
str[0] = c;
str[1] = '';
}
return str;
}

以下是一些错误消息:

191行str[length+1] = '';

% 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 条这样的错误消息,有些是第 190 行的结果,Conditional jump or move depends on uninitialised value(s)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 级入门课程以来已经 2 年了(,但任何关于哪里出错或可能出错的帮助,以及如何调试这些的建议将不胜感激!

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

这部分有多个错误:

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

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

2( 切勿直接realloc目标指针。realloc可能会返回空

所以试着像:

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] = '';

最新更新