我在我的一个班级成员中遇到了一些奇怪的行为,这真的让我陷入了困境,但我肯定没有看到这个问题(很长一周!)
void MyFakeStringClass::readStream( iostream& nInputStream )
{
// Hold the string size
UINT32 size = 0;
// Read the size from the stream
nInputStream.read( reinterpret_cast< char* >( &size ), sizeof( UINT32 ) );
// Create a new buffer
char* buffer = new char[ size ];
// Read the stream
nInputStream.read( buffer, size );
// Save to class member
value = string( buffer );
// Clean up
delete[] buffer;
buffer = NULL;
}
当我使用两个或更多MyFakeStringClass时会出现此问题。 buffer
仍以某种方式包含之前调用MyFakeStringClass::readStream
的数据。
比如说我读了两个字符串'HelloWorld','Test',结果MyFakeStringClass对象包含'HelloWorld'和'TestoWorld'(应该是'HelloWorld','Test')。
第二次访问函数buffer
仍然包含“旧”内存。这是如何实现的,因为它是本地范围和删除的?我已经确认buffer
正以某种方式与调试器共享。
答案 0 :(得分:2)
new char
未初始化内存。它将填充以前使用的内存中留下的任何随机数据。
如果在对readStream的两次调用之间没有其他内存分配,那么很可能你会从相同的地址开始获取缓冲区。
也就是说,你有一个错误,缓冲区不是0终止,你正在使用的构造函数假定它是。你很幸运,你没有遇到很多其他问题。
您可以使用指定长度的构造函数:
value = string( buffer, size );
或者,如果您需要将缓冲区用于绝对需要0终止缓冲区的内容,您还可以将代码更改为:
// Create a new buffer
char* buffer = new char[ size + 1];
// Read the stream
nInputStream.read( buffer, size );
// Add the 0 termination to the end of the string
buffer[size] = '\0';
答案 1 :(得分:1)
您需要使用以下命令创建字符串:
value = string( buffer, size );
如果未指定大小,则假定buffer
是以空字符结尾的字符串。由于没有空终止符,它会读取数据的末尾,并为您提供以前的内存内容。
答案 2 :(得分:0)
它确实具有正确的大小,但是如果你再次调用new并删除new,那么你将获得相同的值,因为内存管理器不会为你初始化任何内容。如果您将它用作空终止字符串,则需要将其初始化为零。