Valgrind在调用wcstombs时报告未初始化的值

时间:2014-03-13 10:34:38

标签: c++ valgrind

我偶然发现了一份Valgrind报告,说我无法自行修复。我有一个函数,可以读取Microsoft" unicode"来自文件的字符串(一系列以字符为前缀的两字节对齐的wchar_t)。示例文件可能如下所示:

0004 0041 0041 0041 0041                 ..A.A.A.A.

以下代码示例读取" unicode"文件中的字符串,并使用wcstombs从中生成一个std :: string。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>

#include <boost/shared_array.hpp>
#include <boost/cstdint.hpp>

std::string read_unicode_string(FILE* f)
{
    std::wstring s = std::wstring();
    wchar_t c;
    boost::uint16_t size;
    if (2 !=fread(&size, 1, 2, f)) {
        return "";
    }

    // Microsoft's "unicode" strings are word aligned.
    for (unsigned int i = 0 ; i < size ; ++i)
    {
        if (2 != fread(&c, 1, 2, f)) {
            break;
        }
        s += c;
    }
    s += L'\0';

    // Convert the wstring into a string
    boost::shared_array<char> conv = boost::shared_array<char>(new char[s.size() + 1]);
    memset(conv.get(), 0, sizeof(char) * (s.size() + 1));
    wcstombs(conv.get(), s.c_str(), s.size());
    return std::string(conv.get());
}

int main(int argc, char** argv)
{
    FILE* f = fopen("test", "rb");
    if (f == NULL) {
        return 1;
    }
    std::cout << read_unicode_string(f) << std::endl;
    fclose(f);
    return 0;
}

尽管看起来确实有效,但valgrind报告说wcstombs的一些跳跃取决于初始值:

==8440== Conditional jump or move depends on uninitialised value(s)
==8440==    at 0x56606C2: wcsnlen (wcsnlen.c:40)
==8440==    by 0x565FCF0: wcsrtombs (wcsrtombs.c:110)
==8440==    by 0x56101A0: wcstombs (wcstombs.c:35)
==8440==    by 0x401488: read_unicode_string(_IO_FILE*) (test.cpp:32)
==8440==    by 0x40157C: main (test.cpp:42)
==8440== 
==8440== Conditional jump or move depends on uninitialised value(s)
==8440==    at 0x55F2D5B: __gconv_transform_internal_ascii (loop.c:332)
==8440==    by 0x565FD41: wcsrtombs (wcsrtombs.c:116)
==8440==    by 0x56101A0: wcstombs (wcstombs.c:35)
==8440==    by 0x401488: read_unicode_string(_IO_FILE*) (test.cpp:32)
==8440==    by 0x40157C: main (test.cpp:42)

我一直在寻找,但我觉得我已经正确地初始化了每个变量。 有没有人在我的代码中看到问题?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

这是一个令人讨厌的错误!如果sizeof(wchar_t)大于2(比方说4)宽字符串&#39;将得到(2)未初始化的字节,在wcstombs中报告为未初始化的值。

答案 1 :(得分:1)

问题不在您的代码中。调用堆栈显示未初始化的变量在wcstombs的实现中的某处使用 - 你所能做的就是尝试告诉valgrind不要检查那个库或者从valgrind的输出中过滤掉这两个消息。