我正在编写我的String类的版本,但Valgrind抱怨我的字符串 <<
运算符的实现 . 错误是在错误的行,如果我通过char打印char它工作得很好 .
我哪里错了?
Valgrind错误:
== 2769 ==条件跳转或移动取决于未初始化的值== 2769 ==在0x4C2AC28:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)== 2769 == by 0x4ECAD60 :std :: basic_ostream>&std :: operator <<>(std :: basic_ostream>&,char const *)(在/ usr / lib / x86_64-linux-gnu / libstdc .so.6.0.17中)== 2769 == by 0x400BD5:operator <<(std :: ostream&,String&)(string.cpp:22)== 2769 == by 0x400AAC:main(main.cpp:12)
我的 <<
字符串运算符:
ostream & operator << (ostream & o, String & inS) {
o << inS._pData << " "; // the wrong line
return o;
}
我的 String
课程:
class String {
public:
unsigned _size;
char * _pData;
String();
String(const char* inCString);
};
构造函数(适用于 char*
):
String::String(const char* inCString) {
_size = strlen(inCString);
_pData = new char[_size + 1];
strncpy(_pData, inCString, _size);
}
Main.cpp的:
int main(int, char**) {
String s1("hello");
cout << s1;
return 0;
}
3 回答
我不建议使用这样的原始字符串 .
然而,罪魁祸首在这里:
或者,也可以手动存储NUL终止字符:
通过缺少NUL终止字符,输出操作将继续运行超过字符串的结尾 . (行为可能看起来没问题,因为角色可能是偶然的,取决于编译器,选项等)
暗示:
考虑使用C风格而不是C API
如果你必须使用C风格
char*
,至少使用stdrup
和free
如果你坚持做NUL终止的字符串,考虑写C方式:
因为您无法在结尾写入零字节 . 你需要:
你应该非常谨慎地使用
n
-反转C字符串函数,因为它们都有微妙的不同语义 .请注意,您没有明确初始化数据成员,而是为它们分配值:
...为了初始化,你应该改为: