0

C または C++ では、ポインターを削除すると、メモリが解放されるだけで、ポインターが 0 に設定されません。ポインターの有効性を確認できないため、プログラマーがポインターの null を確認する方が簡単でした。メモリを解放した後にポインタが 0 に設定された場合。

なぜ「削除」がメモリを解放するためだけに実装されているのか疑問に思っていました。

4

6 に答える 6

4

「ポインタの有効性をチェックすることはできないので、メモリを解放した後にポインタが 0 に設定されていれば、プログラマはポインタの null 性をチェックする方が簡単だったでしょう。」

null 値をチェックすると、コードのサイズと複雑さが増し、バグが隠れる可能性が高くなります。また、誤った安心感が与えられます。ポインター値 (ヌル化前) が他の場所にコピーされていないという保証はありません。また、これにより、値による削除が防止されます。これは、見当違いの null 削除操作を提供するライブラリ (OpenCV など) にとって大きな煩わしさです。

このような非生産的なプラクティスの代わりに、適切なスマート ポインターを使用するなど、適切なクリーンアップを保証し、無効なポインターを防止する手法を使用してください。

于 2012-08-02T13:32:54.837 に答える
1

なぜなら、C++ では (ほとんど) パフォーマンスがすべてだからです。コンパイラにコードを追加させたくない、必要がない。コードに追加していないことをプログラムに実行させたくない場合。

このポインターをチェック/再利用することが確実な場合は、無効にする必要はありません。命令が 1 つ少なくなります。

また、ポインターを削除して に設定するとNULL、既に削除されたメモリを指す他のポインターはどうなりますか? それらは無効にはなりません。これは悪いことを引き起こす可能性があります。

NULL必要に応じて を割り当てるだけです。

于 2012-08-02T13:32:47.203 に答える
1

必要はありません: deleteSBRM ラッパー クラスのデストラクタにいるだけなので、後でポインタにアクセスできる可能性があるものは他にありません:

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;
}
于 2012-08-02T13:33:01.317 に答える
0

deleteポインターに NULL が割り当てられたとしても、何も安全にはなりません。複数のポインタが同じメモリ アドレスを指すことができるため、これらの 1 つに NULL を割り当てても、他のポインタが NULL になることはありません。

于 2012-08-02T13:35:40.523 に答える
0

const ポインター変数を削除できます。NULL に設定することはできません。削除後に変更可能なポインター変数を NULL に設定するだけでは、多少矛盾しているようです。

于 2012-08-02T13:36:32.677 に答える
0

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;
}
于 2012-08-02T13:37:05.657 に答える