2013-08-01 12 views
32

これはかなりよくある質問ですが、私のためにはまだ新しいです!ぶら下がっているポインタは何ですか

私はポインタをぶら下げるという概念を理解しておらず、グーグルでテストしていましたが、テスト方法を書いて これを見つけるにはどうしたらいいですか?私が見つけた例が何であれ 何かを返すものだったので、ここで私は似たようなものを試しています! ありがとう!

void foo(const std::string name) 
{ 
    new_foo(name.c_str()); ///// will it be Dangling pointer?!, with comments/Answer 
          ///// it could be if in new_foo, I store name into Global. 
          ///// Why?! And what is safe then? 
} 

void new_foo(const char* name) 
{ 
    ... print name or do something with name... 
} 
+0

*「?!それはポインタをダングリングされ、コメントを/それが答え」* - いいえ、そうではありません。あなたの最初の例にぶら下がったポインタはありません。あなたがしていることは、完全に100%安全で正確です。 –

+0

私はあなたが*ポインタ*を持たない*ぶら下がりのポインタ*を持つ方法を見ていません。 –

+0

@TheOtherGuy私は、const char *は何も意味しません。同じconst std :: stringを持っています。 –

答えて

38

ダングリングポインタは、例えば、無効データ又はもはや有効でないデータを指し示すポインタである:

Class *object = new Class(); 
Class *object2 = object; 

delete object; 
object = nullptr; 
// now object2 points to something which is not valid anymore 

これもスタック割り当てられたオブジェクトで発生する可能性があります

Object *method() { 
    Object object; 
    return &object; 
} 

Object *object2 = method(); 
// object2 points to an object which has been removed from stack after exiting the function 

c_strによって返されたポインタは、文字列が後で変更されるか破棄されると無効になることがあります。あなたの例では、あなたはそれを変更するようには見えませんが、const char *nameで何をしようとしているのかは明らかではないので、あなたのコードは本質的に安全かどうかわかりません。

たとえば、ポインタをどこかに格納してから、対応する文字列が破棄されると、ポインタは無効になります。 new_fooの範囲内にちょうどconst char *nameを使用すると(たとえば、印刷目的で)、ポインタは有効のままです。

+0

文字列の内容を変更して 'c_str()'によって返されたポインタを無効にすると、OPの例が – Angew

+0

IIRCにぶら下がっていないことを追加することもできます。 – Jack

+0

しかし、文字列は変更されません。また、マルチスレッドアプリケーションであっても、法的に変更する方法はありません。 –

10

ダングリングポインタは、割り当てられていない(すでに解放されている)メモリ領域を指す(NULLでない)ポインタです。

上記の例は、new_fooによって文字列が変更されていない場合には正しいはずです。

+0

...「既に解放された*」を強調! – alk

+0

@MiklósHomolyaその "const" ..あなたはnew_fooで何を修正するのですか? –

+0

"const"の使用はフロントエンドの(コンパイラ)機能であり、これはconst_castによって克服することができます。問題は、関数 'foo'のコードが既に与えられているので、標準準拠の方法でスタック変数 'name'への参照を取得する方法です。 –

2

スタイルの問題として、ぶら下がったポインタは、「それがもはや存在しなくても、依然として存在するポインタ」として説明します。

あなたの場合、ポインターnameは、それが指しているオブジェクトより短い期間存在します。だからそれは決してぶら下がっていません。

一般的なC++クラスの中では、ポインタは非常に短期間で、デストラクタ内でぶら下がります。これは、deleteステートメントがデストラクターの最後の}の前にあり、ポインター自体が最後の}に存在しなくなるためです。これを心配したくない場合は、例を使用してください。 unique_ptr<T>T*ポインタは、完全に安全なunique_ptr::~unique_ptrデストラクタの中で非常に短時間でぶら下がります。

2

出典:here。 Cの場合でもC++と同じですが、

ダングリングポインタ

任意のポインタはなく、任意の変数のメモリアドレスを指している場合、ポインタがまだそのようなメモリ位置を指している間にいくつかの変数は、そのメモリ位置から削除した後。このようなポインタは、ダングリングポインタと呼ばれ、この問題はダングリングポインタの問題として知られています。

最初

enter image description here

その後

enter image description here

#include<stdio.h> 

int *call(); 
int main(){ 

int *ptr; 
ptr=call(); 

fflush(stdin); 
printf("%d",*ptr); 
return 0; 
} 
int * call(){ 

int x=25; 
++x; 

return &x; 
} 

変数xがローカル変数であるため、出力がガベージになります。そのスコープと寿命は関数呼び出しの中にあります。したがって、変数xのアドレスを返した後、xが死んでポインタはまだptrを指していますが、まだその位置を指しています。

-2

ダングリングポインターとダングリングポインターの問題 ポインターが変数のメモリアドレスを指しているが、ポインターがそのようなメモリー位置を指している間に変数がそのメモリー位置から削除された後。

そのポインタはダングリングポインタと呼ばれ、そのときに発生する問題をダングリングポインタ問題と呼びます。

は、ここではいくつかの例です:Dangling Pointer and dangling pointer problem

関連する問題