C または C++ では、ポインターを削除すると、メモリが解放されるだけで、ポインターが 0 に設定されません。ポインターの有効性を確認できないため、プログラマーがポインターの null を確認する方が簡単でした。メモリを解放した後にポインタが 0 に設定された場合。
なぜ「削除」がメモリを解放するためだけに実装されているのか疑問に思っていました。
「ポインタの有効性をチェックすることはできないので、メモリを解放した後にポインタが 0 に設定されていれば、プログラマはポインタの null 性をチェックする方が簡単だったでしょう。」
null 値をチェックすると、コードのサイズと複雑さが増し、バグが隠れる可能性が高くなります。また、誤った安心感が与えられます。ポインター値 (ヌル化前) が他の場所にコピーされていないという保証はありません。また、これにより、値による削除が防止されます。これは、見当違いの null 削除操作を提供するライブラリ (OpenCV など) にとって大きな煩わしさです。
このような非生産的なプラクティスの代わりに、適切なスマート ポインターを使用するなど、適切なクリーンアップを保証し、無効なポインターを防止する手法を使用してください。
なぜなら、C++ では (ほとんど) パフォーマンスがすべてだからです。コンパイラにコードを追加させたくない、必要がない。コードに追加していないことをプログラムに実行させたくない場合。
このポインターをチェック/再利用することが確実な場合は、無効にする必要はありません。命令が 1 つ少なくなります。
また、ポインターを削除して に設定するとNULL
、既に削除されたメモリを指す他のポインターはどうなりますか? それらは無効にはなりません。これは悪いことを引き起こす可能性があります。
NULL
必要に応じて を割り当てるだけです。
必要はありません: delete
SBRM ラッパー クラスのデストラクタにいるだけなので、後でポインタにアクセスできる可能性があるものは他にありません:
template <typename T> struct MyPtr
{
template <typename ...Args> MyPtr(Args &&... args)
: p(new T(std::forward<Args>(args)...)
{ }
~MyPtr()
{
delete p; // done! who cares what `p` is now.
}
MyPtr(MyPtr const &) = delete;
MyPtr & operator=(MyPtr const &) = delete;
T * operator->() { return p; }
private:
T * p;
}
delete
ポインターに NULL が割り当てられたとしても、何も安全にはなりません。複数のポインタが同じメモリ アドレスを指すことができるため、これらの 1 つに NULL を割り当てても、他のポインタが NULL になることはありません。
const ポインター変数を削除できます。NULL に設定することはできません。削除後に変更可能なポインター変数を NULL に設定するだけでは、多少矛盾しているようです。
1 つには、効率上の理由から、削除後にポインター演算を実行したい場合があります。
const int SIZE = 5;
MyObject* foo[SIZE];
// ... initialize foo with new MyObjects...
for (MyObject* i = &foo[0], end = &foo[0] + SIZE; i < end; ++i)
{
delete i;
}