c - wprintf 会导致 valgrind 中的 "conditional jump or move depends on uninitialised value(s)"吗?

标签 c valgrind

我正在尝试编写解决以下问题的函数(这是无关紧要的,我描述它是为了描述下面的代码):

给定一个单词和一个规则,形式为:“lhs->rhs”,其中单词= lhs ^后缀,输出rhs ^后缀,例如:

如果单词是“输入”并且规则是“输入->输出”,则函数将返回单词“输出”,如果规则不能用于该单词,则返回 NULL。

但有一个变化:“lhs”还可能包含数字变量(除了字母之外),例如。 G。 “01->10”,在这种情况下,该规则在用于“niput”时会将“niput”转换为“input”(因此数字对应于某些位置的字母)。

代码如下:

#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>

#define MAX_WORD_SIZE 101

wchar_t *transform_by_rule(wchar_t *word, wchar_t *lhs, wchar_t *rhs)
{
    int i;
    long int wint;
    int lhs_len = wcslen(lhs);
    int rhs_len = wcslen(rhs);
    int word_len = wcslen(word);

    // Initial check - does lhs fit to word
    if (word_len < lhs_len)
        return NULL;
    for (i = 0; i < lhs_len; i++)
    {
        if (iswdigit(lhs[i]))
            continue;
        else
        {
            if (lhs[i] != word[i])
                return NULL;
        }
    }

    wchar_t *result =
        malloc((rhs_len + 1) * sizeof(wchar_t));
    wchar_t int_wchar_map[10];
    for (i = 0; i < lhs_len; i++)
    {
        if (iswdigit(lhs[i]))
        {
            wint = lhs[i] - L'0';
            int_wchar_map[wint] = word[i];
        }
    }
    for (i = 0; i < rhs_len; i++)
    {
        if (iswdigit(rhs[i]))
        {
            wint = rhs[i] - L'0';
            result[i] = int_wchar_map[wint];
        }
        else
        {
            result[i] = rhs[i];
        }
    }
    return result;
}


int main()
{
    wchar_t word[MAX_WORD_SIZE];
    wchar_t lhs[MAX_WORD_SIZE];
    wchar_t rhs[MAX_WORD_SIZE];
    wscanf(L"%ls", word);
    wscanf(L"%ls", lhs);
    wscanf(L"%ls", rhs);
    wchar_t *result = transform_by_rule(word, lhs, rhs);
    if (result != NULL)
    {
        wprintf(L"%ls\n", result); // line 67
        free(result);
    }
    else
    {
        puts("Rule doesn't fit to word.");
    }
    return 0;
}

问题就在这里。当在 valgrind 下运行输入“a”(单词)、“a”(左)、“b”(右)时,valgrind 输出错误:

==6094== Conditional jump or move depends on uninitialised value(s)
==6094==    at 0x4C30E19: wcslen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6094==    by 0x4E8C3F6: vfwprintf (in /usr/lib64/libc-2.20.so)
==6094==    by 0x4EA7448: wprintf (in /usr/lib64/libc-2.20.so)
==6094==    by 0x4009AA: main (main.c:67)

我没有发现我的代码有任何问题。这是 wprintf() 的问题吗?

最佳答案

transform_by_rule() 返回之前,

result 不是以零结尾的。因此,当在其返回值上调用 wprintf() 时,wprintf() 可能会越界读取,因为它可能不会在分配的内存块内遇到终止宽字符。

使用wchar_t *result = calloc(rhs_len + 1, sizeof(wchar_t));,如果您确定没有超出内的边界,您会自动获得正确终止的字符串>transform_by_rule()

关于c - wprintf 会导致 valgrind 中的 "conditional jump or move depends on uninitialised value(s)"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30672981/

相关文章:

c - 为什么我的程序跳过 for 循环? C

ruby - 查找 Ruby 中内存泄漏的原因

html - 在C中解析XML的算法

c - 你如何理解下面的按位运算?

c - url在c中编码一个utf-8字符串?

c - 我怎么能模拟 void 类型的函数?

c++ - 了解 C++ 分配的内存量

python - 让 Valgrind 检测 Python 脚本 : 调用的 C++ 程序的内存泄漏

C++ 太多大小为 4 的写入/读取

c - 如何读取 CTRL-D 序列之前的所有输入?