Valgrind在调用wcustoms时报告未初始化的值
Valgrind reports uninitialized value when calling wcstombs
我无意中发现了一个我无法自己修复的Valgrind报告。我有一个函数从文件中读取Microsoft"unicode"字符串(一系列以大小为前缀的双字节对齐的wchar_t)。示例文件可能如下所示:
0004 0041 0041 0041 0041 ..A.A.A.A.
下面的代码示例从文件中读取"unicode"字符串,并使用wcstombs从中生成一个std::字符串。
#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' ';
// 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报告说,一些跳转在wcustoms依赖于一个初始值:
==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)
我一直在寻找,但我觉得我已经正确初始化了每个变量。有人看到我代码中的问题了吗?
提前感谢您的帮助!
这是一个严重的错误!如果sizeof(wchar_t)
大于2(假设为4),宽字符串's'将获得(2)个未初始化的字节,这些字节在wcstombs
中报告为未初始化的值(s)。
问题不在您的代码中。调用栈显示未初始化的变量在wcstombs
实现中的某个地方使用-您所能做的就是尝试告诉valgrind不要检查该库或从valgrind的输出中过滤这两条消息。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 内存清理程序报告全局对象构造中未初始化值的使用
- Clang++ 6.0 内存清理器未报告返回值指示条件分支的函数中的未初始化局部变量
- 为什么 GCC 不报告未初始化的变量
- valgrind 在使用 std::make_shared 和虚拟继承时报告的未初始化值
- 从nodejs模块初始化函数报告失败
- 哪些工具可以报告未初始化变量的此类使用
- 使用{}报告未使用的变量进行统一初始化
- Valgrind报告标准库(vfprintf.c)中未初始化的值
- Valgrind报告sqlite3_step中未初始化的值
- valgrind报告BSONObj::toString中未初始化的值,使用GENOID创建一个简单的BSON对象
- Valgrind在调用wcustoms时报告未初始化的值