C++ удаляет - Он удаляет мои объекты, но я могу все еще получить доступ к данным?

Я записал простую, рабочую игру Тетриса с каждым блоком как экземпляр класса singleblock.

class SingleBlock
{
    public:
    SingleBlock(int, int);
    ~SingleBlock();

    int x;
    int y;
    SingleBlock *next;
};

class MultiBlock
{
    public:
    MultiBlock(int, int);

    SingleBlock *c, *d, *e, *f;
};

SingleBlock::SingleBlock(int a, int b)
{
    x = a;
    y = b;
}

SingleBlock::~SingleBlock()
{
    x = 222;
}

MultiBlock::MultiBlock(int a, int b)
{
    c = new SingleBlock (a,b);
    d = c->next = new SingleBlock (a+10,b);
    e = d->next = new SingleBlock (a+20,b);
    f = e->next = new SingleBlock (a+30,b);
}

У меня есть функция, которая сканирует для полной строки и пробегает связанный список блоков, удаляя соответствующие и повторно присваиваясь-> прямые указатели.

SingleBlock *deleteBlock;
SingleBlock *tempBlock;

tempBlock = deleteBlock->next;
delete deleteBlock;

Игровые работы, блоки удалены правильно, и все функционирует, как это, как предполагается. Однако на контроле я могу все еще получить доступ к случайным битам удаленных данных.

Если я, printf, которые каждый из удаленных singleblocks "x" оценивает ПОСЛЕ их удаления, некоторые из них, возвращают случайный мусор (подтверждение удаления) и некоторые из них, возвращаюсь 222, говоря мне даже при том, что деструктор назвали, данные не были на самом деле удалены из "кучи". Много идентичных пробных версий показывают, что это всегда - те же определенные блоки, которые не удалены правильно.

Результаты:

Existing Blocks:
Block: 00E927A8
Block: 00E94290
Block: 00E942B0
Block: 00E942D0
Block: 00E942F0
Block: 00E94500
Block: 00E94520
Block: 00E94540
Block: 00E94560
Block: 00E945B0
Block: 00E945D0
Block: 00E945F0
Block: 00E94610
Block: 00E94660
Block: 00E94680
Block: 00E946A0

Deleting Blocks:
Deleting ... 00E942B0, X = 15288000
Deleting ... 00E942D0, X = 15286960
Deleting ... 00E94520, X = 15286992
Deleting ... 00E94540, X = 15270296
Deleting ... 00E94560, X = 222
Deleting ... 00E945D0, X = 15270296
Deleting ... 00E945F0, X = 222
Deleting ... 00E94610, X = 222
Deleting ... 00E94660, X = 15270296
Deleting ... 00E94680, X = 222

Способность состоит в том, чтобы получить доступ к данным из-за ожидаемой могилы?

Извините, если это немного долго обветрено.

30
задан Brian Tompsett - 汤莱恩 4 July 2015 в 13:34
поделиться

11 ответов

Ожидается ли возможность доступа к данным из загробного мира?

Технически это известно как неопределенное поведение. Не удивляйтесь, если вам предложат банку пива.

78
ответ дан 27 November 2019 в 22:57
поделиться

Это приведет к неопределенному поведению, и удаление освобождает память, оно не инициализирует ее заново с нуля.

Если вы хотите обнулить, сделайте:

SingleBlock::~SingleBlock()

{    x = y = 0 ; }
0
ответ дан 27 November 2019 в 22:57
поделиться

Да, временами этого можно ожидать. В то время как new резервирует место для данных, delete просто аннулирует указатель, созданный с помощью new , позволяя записывать данные в ранее зарезервированные места; это не обязательно удаляет данные. Однако вам не следует полагаться на такое поведение, потому что данные в этих местах могут измениться в любое время, что может привести к неправильному поведению вашей программы. Вот почему после использования delete для указателя (или delete [] в массиве, выделенном с помощью new [] ), вы должны присвоить ему NULL, поэтому что вы не можете изменить неверный указатель, предполагая, что вы не будете выделять память с помощью new или new [] перед повторным использованием этого указателя.

0
ответ дан 27 November 2019 в 22:57
поделиться

После удаления объекта не определено, что произойдет с содержимым занимаемой им памяти. Это означает, что эта память свободна для повторного использования, но реализации не нужно перезаписывать данные, которые были там изначально, и не нужно немедленно повторно использовать память.

Вы не должны обращаться к память после того, как объект исчез, но неудивительно, что некоторые данные там остались нетронутыми.

1
ответ дан 27 November 2019 в 22:57
поделиться

Он пока не обнулит / не изменит память ... но в какой-то момент коврик вырвется у вас из-под ног.

Нет, это, конечно, непредсказуемо: это зависит от того, насколько быстро происходит выделение / освобождение памяти.

0
ответ дан 27 November 2019 в 22:57
поделиться

Система не очищает память, когда вы освобождаете ее с помощью delete () . Таким образом, содержимое остается доступным до тех пор, пока память не будет назначена для повторного использования и перезаписи.

2
ответ дан 27 November 2019 в 22:57
поделиться

Куча памяти подобна кучке классных досок. Представьте, что вы учитель. Пока вы преподаете в классе, доска принадлежит вам, и вы можете делать с ней все, что захотите. Вы можете рисовать на нем и перезаписывать материал, как хотите.

Когда урок закончится, и вы собираетесь выйти из комнаты,

3
ответ дан 27 November 2019 в 22:57
поделиться

Удалить ничего не удаляет - он просто отмечает память как «свободную для повторного использования». Пока какой-либо другой вызов распределения не резервирует и не заполняет это пространство, он будет иметь старые данные. Однако полагаться на это - большой запрет, в основном, если вы что-то удаляете, забудьте об этом.

Одна из практик в этом отношении, которая часто встречается в библиотеках, - это функция Delete:

template< class T > void Delete( T*& pointer )
{
    delete pointer;
    pointer = NULL;
}

Это предотвращает случайное удаление доступ к недействительной памяти.

Обратите внимание, что вполне нормально вызвать delete NULL; .

9
ответ дан 27 November 2019 в 22:57
поделиться

Ожидается ли возможность доступа к данным из могилы?

В большинстве случаев да. Вызов удаления не обнуляет память.

Обратите внимание, что поведение не определено. При использовании некоторых компиляторов память может быть обнулена. Когда вы вызываете delete, происходит то, что память помечается как доступная, поэтому в следующий раз, когда кто-то выполнит new , память может быть использована.

Если подумать, это логично - когда вы сообщить компилятору, что вас больше не интересует память (используя delete ), почему компьютер должен тратить время на ее обнуление.

31
ответ дан 27 November 2019 в 22:57
поделиться

Это то, что C ++ называет неопределенным поведением - у вас может быть доступ к данным, а может и нет. В любом случае, это неправильно.

9
ответ дан 27 November 2019 в 22:57
поделиться

delete освобождает память, но не изменяет ее и не обнуляет. Тем не менее вам не следует обращаться к освобожденной памяти.

1
ответ дан 27 November 2019 в 22:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: