私が求めているのは、 nullptr が割り当てられていてもポインターを削除する必要があるかどうかです。
たとえば、次の場合です。
std::string* foo = new std::string ("foo");
foo = nullptr;
nullptr が解放される前にメモリが占有されていますか、それともメモリ リークに直面していますか?
いいえ、このコードは で割り当てたオブジェクトをリークしますnew
。
オブジェクトが で割り当てられている場合はnew
、 で割り当てを解除する必要がありますdelete
。
私が求めているのは、 nullptr が割り当てられていてもポインターを削除する必要があるかどうかです。
あなたが使っている用語は、あなたがこれについて間違った方法で考えていることを示しています。削除する必要があるのはポインターではなく、オブジェクトです。ポインターは、コードがオブジェクトを参照するための手段にすぎません。ポインター変数には、オブジェクトのアドレスが含まれます。すべてが同じオブジェクトを参照する複数のポインター変数を持つことができます。ポインターを削除するのではなく、オブジェクトを削除します。
さて、解放を次のように書くのは奇妙に思えるかもしれません。
delete foo;
単純に、ポインター fooを削除することを意味すると考えるかもしれません。しかし、それはそうではありません。つまり、アドレスが foo に格納されているオブジェクトを削除します。
これはメモリ リークです。ただし、オブジェクトが自動的に削除されることを望むのは不合理ではありません。これは標準ライブラリでサポートされています:
std::unique_ptr<std::string> foo = new std::string ("foo");
//better:
auto foo = std::make_unique<std::string>("foo");
//also see std::shared_ptr and std::make_shared
foo = nullptr; //automatically deletes the string
手動でメモリを管理することは不必要に難しいため、コード内にnew
またはコードを含めるのは悪いスタイルと見なされます。delete
コード内の new ごとに delete を使用しています。これは間違いなくメモリリークです。
コメントごとに編集:- スマート ポインターを使用している場合は、メモリ管理の詳細を気にする必要はありません。
new によって割り当てられたメモリは、delete によって解放する必要があります。そうしないと、メモリ リークが発生します。次のように割り当てた場合:
std::string *p = new std::string();
次のように割り当てを解除します。
delete p;
次のように割り当てた場合:
std::string *p = new std::string[10]; // more than one
次のように割り当てを解除します。
delete [] p;