类成员中的动态内存使用

时间:2010-02-07 19:12:57

标签: c++ memory memory-management

我在我的一个班级成员中遇到了一些奇怪的行为,这真的让我陷入了困境,但我肯定没有看到这个问题(很长一周!)

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正以某种方式与调试器共享。

3 个答案:

答案 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,那么你将获得相同的值,因为内存管理器不会为你初始化任何内容。如果您将它用作空终止字符串,则需要将其初始化为零。