C ++では、スタックを巻き戻した後もポインタは有効なままですか?
5 に答える
これは、ポイントされたオブジェクトのストレージに依存します。そのオブジェクトがスタック割り当てされた場合、ポインタは確実に無効になります。スタックをほどくと、オブジェクトが適切に破棄されます。オブジェクトがヒープに割り当てられた場合、スタックの巻き戻し中にオブジェクトの割り当てを解除するRAII変数がある場合にのみ、ポインターは無効になります。
いいえ。スタックを使用すると、スタックの負傷していない部分のスコープで宣言されているすべての変数/ポインターが破棄されます。
Storage Type
また、ルールは変数のを考慮に入れます。
例:static
変数は関数呼び出し間でその値を保持します。これは、スタックの巻き戻し中に変数が破棄されないことを意味します。これは、静的変数がスタックではなく、BSSまたはデータセグメントに格納されているためです。
Local variables
関数内のスタックに作成された(Auto storage type
)は、関数が戻ってスタックの巻き戻しが行われるときに常に破棄されます。
ヒープにメモリが割り当てられているポインタは、スタックではなくヒープに割り当てられているため、スタックの巻き戻し時に破棄されません。
覚えておくべき重要なルールの1つは、関数内のローカル変数へのポインターや参照を決して返さないことです。ポインタまたは参照にはガベージ値が含まれます。
それはあなたのポインタが何を指しているかに依存します。ヒープメモリを指している場合でも、有効なままです。スタックメモリを指している場合は無効になります。
いくつかの例を考えてみましょう。
void* f1a()
{
void* p = malloc(10);
return p;
}
...と同じです...
void* f1b()
{
return malloc(10);
}
ポインタはヒープへのポインタであり、スタック、関数呼び出し、およびプログラムスコープから独立しているため、これで問題ありません。関数が戻ると、ポインタ値がコピーされます。
int* f2()
{
int x;
return &x; // pointer to x - about to become invalid!
}
上記はx
、スタック上の変数へのポインターを返します。この変数はx
、関数が戻るときに再利用(失われる)されます。
私が重要だと思うもう一つのことを述べるだけです
私たちはこの声明を持っていると言います
obj* objptr = new obj(9) //allocate memory on heap and use constructor
ここで例外が発生した場合..メモリヒープが再リリースされます....つまり、メモリリークはありません...
理由は....スタックの巻き戻しのためではありません...しかし、新しい演算子が次の生成されたコードに変換される方法のために、trycatchステートメントが新しい演算子に実装されます...このようなもの...
void * operator new(size_t s)
{
try
{
void * ptr=new(malloc (s))sample(); //placement new
ptr->...
}
catch(..)
{
operator delete(ptr); //<= notice here so if an exception occur then first it is caught here which releases the memory
}
}
ただし、オブジェクト内でメモリ割り当てが行われた場合でも、それは解放されません。