2015-02-08 2 views
-2

Есть ли веские основания для не clear/zero данные элемента элемента элемента в деструкторе? Похоже, что это следует рассматривать стандартную практику для опрятности или личной жизни, так как существует мыслимые способы повторно считывать данные с удаленным объекта:Должны ли данные члена всегда очищаться/нулеваться в деструкторе?

#include <iostream> 

class Box { 
    public: 
     Box(int s) : secret(s), buffer(this) {} 
     ~Box() {} 
     /*BETTER DESTRUCTOR ~Box() {secret = 0;}*/ 
     void print() {std::cout << secret << std::endl;} 
    private: 
     void* buffer; 
     int secret; 
}; 

int main() { 
    Box* carton = new Box(8675309); 
    Box* crate = carton; 
    delete carton; 
    crate->print(); 
} 

(Обратите внимание, что buffer необходимо только потому, что без него, что-то переписывает secret перед тем crate->print().)

ли он принимать «слишком много времени» обнулить данные элемента, так что это считается не стоит (особенно если вы должны идти по массиву и нулю каждый элемент) ?

По-видимому, это не проблема с более сложными элементами данных, такими как контейнеры STL, потому что their destructors clear their data, а также pointers should not be cleared для целей отладки.

+0

Вы недопонимаете тот первый вопрос, на который вы ссылаетесь. 'std :: vector' clear просто удаляет содержащиеся в нем элементы, он не« очищает », а затем в том смысле, что вы здесь. – Mat

+0

В коде есть неопределенное поведение. Обнуление вещей в деструкторе не изменит этого. – juanchopanza

+0

@juanchopanza Я понимаю, что код надуман. Я просто хотел привести пример, который показывает, что 'delete' только перераспределяет память, а не фактически« очищает »то, что там хранилось. –

ответ

7

IF ваш класс содержит «секретные» вещи, а затем очистка его от дескрипции поможет маленькому биту сохранить его в памяти, которую вы больше не имеете. Но это не значит, что вы можете помешать кому-то сделать снимок памяти, когда ваше приложение активирует объект, так как мера безопасности, это довольно плохо ...

Но, в общем, нет, деструктор должен а не нулевой контент в классе. Это пустая трата времени.

Это не то же самое, что «он не должен удалять члены в динамически распределенных структурах», конечно, что и есть, например, std::vector. Он уничтожит все содержимое вектора, поскольку не известно, что делает деструктор для этих элементов.

1

Достаточно приличный оптимизатор удалит задание secret = 0.

Причина этого довольно проста. Одна из самых простых оптимизаций - удалить инструкции, которые не имеют никакого эффекта. Общим классом таких инструкций являются записи, за которыми не следует чтение. Поскольку this->secret=0 - это последнее утверждение в вашем деструкторе, компилятор может тривиально определить, что вы больше никогда не будете читать secret. Удаление инструкции - легкая экономия.

Вы можете задаться вопросом, почему эта оптимизация выполняется, как часто эта ситуация может возникнуть? Ответ «довольно часто», потому что оптимизация не происходит изолированно. Например, такая запись без чтения является обычным явлением при встраивании функции, которая возвращает код ошибки, когда вызывающий абонент не проверяет код ошибки. После inlining это запись в код ошибки без соответствующего чтения.