コンテキスト:私は頭をポインターに巻き付けようとしていますが、数週間前に学校で見ましたが、今日の練習中に愚かなことに遭遇しましたか?問題、それはあなたにとって非常に簡単かもしれませんが、私はほとんど、またはまったくプログラミングの経験がありません。
ポインターの削除についてSOでかなりの数の質問を見てきましたが、それらはすべて、単純なポインター(または適切な用語)ではなく、クラスの削除に関連しているようです。私が実行しようとしているコード:
#include <iostream>;
using namespace std;
int main() {
int myVar,
*myPointer;
myVar = 8;
myPointer = &myVar;
cout << "delete-ing pointers " << endl;
cout << "Memory address: " << myPointer << endl;
// Seems I can't *just* delete it, as it triggers an error
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// Error: a.out(14399) malloc: *** error for object 0x7fff61e537f4:
// pointer being freed was not allocated
// *** set a breakpoint in malloc_error_break to debug
// Abort trap: 6
// Using the new keyword befor deleting it works, but
// does it really frees up the space?
myPointer = new int;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer continues to store a memory address.
// Using NULL before deleting it, seems to work.
myPointer = NULL;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer returns 0.
}
だから私の質問は:
長い質問で申し訳ありませんが、これをできるだけ明確にしたかったので、繰り返しますが、私はプログラミングの経験がほとんどないので、素人の言葉を使ってこれに答えることができれば、とても感謝しています!
1&2
myVar = 8; //not dynamically allocated. Can't call delete on it.
myPointer = new int; //dynamically allocated, can call delete on it.
最初の変数がスタックに割り当てられました。 new
演算子を使用して、動的に(ヒープ上に)割り当てたメモリでのみdeleteを呼び出すことができます。
3。
myPointer = NULL;
delete myPointer;
上記は何もしませんでした。ポインターがNULLを指していたため、何も解放しませんでした。
次のことは行わないでください:
myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all
リークしたメモリ(割り当てた新しいint)を残して、NULLをポイントしました。指していたメモリを解放する必要があります。割り当てられたnew int
にアクセスする方法がなくなったため、メモリリークが発生しました。
正しい方法:
myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL
より良い方法:
C++を使用している場合、しないでください生のポインターを使用します代わりに スマートポインター を使用すると、これらのことをほとんどオーバーヘッドなしで処理できます。 C++ 11には 複数 が付属しています。
ポインターがどのように機能するかを完全に理解していないと思います。
いくつかのメモリを指すポインタがある場合、次の3つのことを理解する必要があります。
-ポインター(メモリー)によって「ポイントされたもの」があります
-このメモリアドレス
-すべてのポインターのメモリを削除する必要はありません。動的に割り当てられたメモリのみを削除する必要があります(new
演算子を使用)。
想像してみてください:
int *ptr = new int;
// ptr has the address of the memory.
// at this point, the actual memory doesn't have anything.
*ptr = 8;
// you're assigning the integer 8 into that memory.
delete ptr;
// you are only deleting the memory.
// at this point the pointer still has the same memory address (as you could
// notice from your 2nd test) but what inside that memory is gone!
あなたがやったとき
ptr = NULL;
// you didn't delete the memory
// you're only saying that this pointer is now pointing to "nowhere".
// the memory that was pointed by this pointer is now lost.
C++では、delete
を指すポインターをnull
にしようとすることができますが、実際には何もせず、エラーは発生しません。
ポインターは、削除する必要がないという点で通常の変数に似ています。関数実行の終了時および/またはプログラムの終了時にメモリから削除されます。
ただし、次のように、ポインタを使用してメモリの「ブロック」を割り当てることができます。
int *some_integers = new int[20000]
これにより、20000整数のメモリスペースが割り当てられます。スタックのサイズは限られているため、スタックオーバーフローエラーなしで大量の「int」を台無しにしたい場合に便利です。
Newを呼び出すたびに、プログラムの最後で「削除」する必要があります。そうしないと、メモリリークが発生し、他のプログラムが使用するために割り当てられたメモリスペースが返されません。これをする:
delete [] some_integers;
お役に立てば幸いです。
C++には、newごとにdeleteがあるルールがあります。
newが呼び出されることはありません。したがって、coutが出力するアドレスは、myVarのメモリ位置のアドレス、またはこの場合myPointerに割り当てられた値です。書くことにより:
myPointer = &myVar;
あなたは言う:
myPointer = myVarのデータが保存されている場所のアドレス
削除されたメモリの場所を指すアドレスを返します。最初にポインターを作成し、その値をmyPointerに割り当て、2番目に削除し、3番目に印刷するためです。したがって、myPointerに別の値を割り当てない限り、削除されたアドレスは残ります。
NULLは0に等しいため、0を削除するため、何も削除しません。そして、それはあなたがしたので0を出力するロジックです:
myPointer = NULL;
等しい:
myPointer = 0;
int value, *ptr;
value = 8;
ptr = &value;
// ptr points to value, which lives on a stack frame.
// you are not responsible for managing its lifetime.
ptr = new int;
delete ptr;
// yes this is the normal way to manage the lifetime of
// dynamically allocated memory, you new'ed it, you delete it.
ptr = nullptr;
delete ptr;
// this is illogical, essentially you are saying delete nothing.