【问题标题】:Valgrind error conditional jumpValgrind 错误条件跳转
【发布时间】:2015-08-04 12:32:21
【问题描述】:

我正在编写一个加载输入的程序,直到输入一个特定的单词,在这种情况下它的单词“konec”。虽然我的程序似乎工作正常,但我无法解决这个 Valgrind 错误

==16573== Memcheck, a memory error detector   
==16573== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.  
==16573== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info  
==16573== Command: ./s_main_o  
==16573==   
==16573== Conditional jump or move depends on uninitialised value(s)  
==16573==    at 0x4C2A020: strcmp (mc_replace_strmem.c:711)  
==16573==    by 0x4008D7: main (main.c:41)  
==16573==  Uninitialised value was created by a heap allocation  
==16573==    at 0x4C28CCE: realloc (vg_replace_malloc.c:632)  
==16573==    by 0x40089C: main (main.c:38)  
==16573==   
==16573== Conditional jump or move depends on uninitialised value(s)  
==16573==    at 0x4C2A024: strcmp (mc_replace_strmem.c:711)  
==16573==    by 0x4008D7: main (main.c:41)  
==16573==  Uninitialised value was created by a heap allocation  
==16573==    at 0x4C28CCE: realloc (vg_replace_malloc.c:632)  
==16573==    by 0x40089C: main (main.c:38)  
==16573==   
==16573==   
==16573== HEAP SUMMARY:  
==16573==     in use at exit: 0 bytes in 0 blocks  
==16573==   total heap usage: 8 allocs, 8 frees, 1,125 bytes allocated  
==16573==   
==16573== All heap blocks were freed -- no leaks are possible  
==16573==   
==16573== For counts of detected and suppressed errors, rerun with: -v  
==16573== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)  

这里是使用的部分代码

int main() {

    int numberOfWords, i;
    char** words;
    char* word;
    int* rarity;
    char* konec = "konec";
    int amount = 0;
    double percentage;
    words = malloc(10 * sizeof (char*));
    rarity = calloc(256, sizeof (int));
    numberOfWords = 0;
    words[0] = 0;
    int working = 1;

    while (working == 1) {
        int length = 0;
        word = calloc((length + 1),sizeof (char));
        char c;
        while ((c = getchar()) != EOF) {
            if (c == ' ' || c == '\n') {
                break;
            }
            length++;
            word = realloc(word, length + 1);
            word[length - 1] = c;
        }
        if (strcmp(word, konec) == 0) {
            working = 0;
            free(word);
            break;
        }
    }
}

我发现很多话题都在讨论同一个问题,但无论如何我都找不到解决方案。感谢您的回答。

【问题讨论】:

  • 不要像那样使用realloc(),使用临时指针,并在取消引用指针之前始终检查任何*alloc函数没有返回NULL
  • 您需要在word 中添加一个空终止符。目前,strcmp 读取超出您分配的内存的末尾以寻找第一个零字节。
  • char c; 你应该把它变成一个整数。

标签: c valgrind


【解决方案1】:

问题是您没有在重新分配时添加空终止符:

word = realloc(word, length + 1);
word[length - 1] = c;

此时,word 字符串尚未终止,因此strcmp 可能会在其末尾寻找空终止符。例如,当您键入 "ko" 时,strcmp 将确定字符 0 和 1 相同,并尝试检查 word[2] - 您的程序未设置的位置。

添加这一行来解决问题:

word[length] = '\0';

当与konec 比较不成功时,您还应该将代码添加到free word

注意:您没有正确使用realloc:与其将其分配回word,不如将​​其分配给temp,并检查NULL。否则,当realloc 失败时,您将无法释放先前分配的字。

【讨论】: