ダングリング ポインターとメモリ リークの違いがわかりません。これら2つの用語はどのように関連していますか?
8 に答える
ダングリング ポインターは、既に解放されているメモリを指しています。ストレージは割り当てられなくなりました。アクセスしようとすると、セグメンテーション違反が発生する可能性があります。
ダングリング ポインターで終わる一般的な方法:
char *func()
{
char str[10];
strcpy(str, "Hello!");
return str;
}
//returned pointer points to str which has gone out of scope.
ローカル変数であったアドレスを返しています。これは、コントロールが呼び出し元の関数に返されるまでに範囲外になります。(未定義の動作)
ダングリング ポインターのもう 1 つの一般的な例は、メモリ上で free が明示的に呼び出された後、ポインターを介してメモリ位置にアクセスすることです。
int *c = malloc(sizeof(int));
free(c);
*c = 3; //writing to freed location!
メモリ リークは、解放されていないメモリです。アクセスする方法がなくなったため、アクセス (または解放) する方法がありません。(たとえば、現在別の場所を指している、動的に割り当てられた(解放されていない)メモリ位置への唯一の参照であったポインタ。)
void func(){
char *ch = malloc(10);
}
//ch not valid outside, no way to access malloc-ed memory
char-ptr ch は、関数の最後でスコープ外になるローカル変数で、動的に割り当てられた10 バイトをリークします。
これらは互いに正反対のものと考えることができます。
メモリの領域を解放しても、その領域へのポインターを保持している場合、そのポインターはぶら下がっています。
char *c = malloc(16);
free(c);
c[1] = 'a'; //invalid access through dangling pointer!
ポインターを失ってもメモリを割り当てたままにすると、メモリ リークが発生します。
void myfunc()
{
char *c = malloc(16);
} //after myfunc returns, the the memory pointed to by c is not freed: leak!
ダングリング ポインターは、期待するオブジェクトの型に対して無効なメモリを参照する値 (NULL ではない) を持つポインターです。たとえば、オブジェクトへのポインターを設定した場合、そのメモリを無関係なもので上書きしたり、動的に割り当てられた場合はメモリを解放したりします。
メモリ リークは、ヒープからメモリを動的に割り当てたが、メモリへのすべての参照が失われたために解放されなかった場合に発生します。
これらは、特に動的に割り当てられたメモリに関して、誤って管理されたポインターに関連する状況であるという点で関連しています。ある状況 (ダングリング ポインター) では、メモリを解放した可能性がありますが、後でそれを参照しようとしました。もう 1 つの場合 (メモリ リーク)、メモリを完全に解放するのを忘れています。
ぶら下がりポインター
ポインタが変数のメモリアドレスを指しているが、そのメモリ位置から変数が削除された後、ポインタがまだそのようなメモリ位置を指している場合。このようなポインターはダングリング ポインターと呼ばれ、この問題はダングリング ポインター問題として知られています。
#include<stdio.h>
int *call();
void main(){
int *ptr;
ptr=call();
fflush(stdin);
printf("%d",*ptr);
}
int * call(){
int x=25;
++x;
return &x;
}
出力: ガベージ値
注: 一部のコンパイラでは、ローカル変数または一時変数のアドレスを返す警告メッセージが表示される場合があります。
説明: 変数 x はローカル変数です。そのスコープと有効期間は関数呼び出し内にあるため、x 変数 x のアドレスを返した後、x は無効になり、ポインターはまだその場所を指しています。
この問題の解決策: 変数 x を静的変数として作成します。つまり、ポインティングオブジェクトが削除されたポインターは、ダングリングポインターと呼ばれます。
メモリーリーク
コンピューター サイエンスでは、コンピューター プログラムがメモリ割り当てを正しく管理しないと、メモリ リークが発生します。簡単に言うと、メモリを割り当てましたが、Free ではありません。他の言語用語では、解放しないと言い、メモリ リークを呼び出します。これは、アプリケーションにとって致命的であり、予期しないクラッシュです。
ポインターは、動的変数と呼ばれる変数へのユーザー定義スコープを作成するのに役立ちます。動的変数は、単一の変数、同じタイプの変数のarray
グループ ( )、または異なるタイプの変数のグループ( ) にすることができますstruct
。デフォルトのローカル変数のスコープは、制御が関数に入ると開始し、制御がその関数から出ると終了します。デフォルトのグローバル変数スコープは、プログラムの実行時に開始され、プログラムが終了すると終了します。
ただし、ポインターによって保持される動的変数のスコープは、プログラム実行の任意の時点で開始および終了することができ、プログラマーが決定する必要があります。ダングリングとメモリ リークが発生するのは、プログラマがスコープの終了を処理しない場合のみです。
free
プログラマーが動的変数のスコープの終了(ポインターの) コードを記述しないと、メモリ リークが発生します。いずれにせよ、プログラムが完全なプロセス メモリを終了すると、このリークされたメモリも解放されます。しかし、長時間実行されているプロセスには非常に深刻な問題が発生します。
動的変数のスコープが終了(解放)しNULL
たら、ポインタ変数に割り当てます。そうしないと、コードが誤ってアクセスすると、未定義の動作が発生します。したがって、ぶら下がっているポインターは、スコープが既に終了している動的変数を指しているポインターに他なりません。
メモリ リーク: ヒープにメモリ領域があるが、スタックにそのメモリを指す変数がない場合。
char *myarea=(char *)malloc(10);
char *newarea=(char *)malloc(10);
myarea=newarea;
ダングリング ポインター: スタック内にポインター変数があるが、ヒープ内にメモリがない場合。
char *p =NULL;
スペースを割り当てずに逆参照しようとするダングリング ポインターは、セグメンテーション フォールトを引き起こします。