Динамическое использование памяти в классе - PullRequest
0 голосов
/ 07 февраля 2010

Я получаю странное поведение в одном из моих учеников, и это действительно заставляет меня заморачиваться, но я определенно не вижу проблемы (долгая неделя!)

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's. buffer все еще содержит данные о предыдущих вызовах MyFakeStringClass::readStream.

Скажем, например, что я прочитал в двух строках «HelloWorld», «Test», полученные объекты MyFakeStringClass содержат «HelloWorld» и «TestoWorld» (должно быть «HelloWorld», «Test»).

При втором доступе к функции buffer все еще содержит «старую» память. Как это возможно, поскольку он локально ограничен и удален? Я подтвердил, что buffer каким-то образом передается отладчику.

Ответы [ 3 ]

2 голосов
/ 07 февраля 2010

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 голос
/ 07 февраля 2010

Вам нужно создать строку, используя:

value = string( buffer, size );

Если вы не укажете размер, он будет считать buffer строкой с нулевым символом в конце. Так как нет нулевого терминатора, он читает после конца данных и дает вам предыдущее содержимое памяти.

0 голосов
/ 07 февраля 2010

Он имеет правильный размер, но если вы вызываете new и удаляете затем new снова, вы получите то же значение, потому что менеджер памяти ничего не инициализирует для вас. Если вы используете ее как строку с нулевым символом в конце, вам нужно инициализировать ее нулем самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...