2017-05-15 1 views
0

のメカニズム、以下のコードを確認してください。私が誤ってC++でこの問題を見つけましたが、完全にそれが起こったかわからなかったのshared_ptr

int main() { 
     int *aptr = new int(20); //Declare an integer space with 20, and aptr points to it 
     shared_ptr<int> a(aptr); //Declare a shared_ptr to points where aptr points 

     stringstream ss; 
     ss << a; 
     const char *chstr = ss.str().c_str(); // Save the address as string 

     void *address; 
     sscanf(chstr, "%p", (void **)&address); // Convert string back to pointer 

     a = NULL; // Free the shared pointer 
     cout << *reinterpret_cast<int*>(address) << endl; // Output: 0, 20 has gone 

     return 0; 
} 

は、アドレスがされている理由を誰が私が言うことができるです解放された?
私は元の整数ポインタ "aptr"を操作しませんでしたが、何とかshared_ptrのためにスペースが消えましたか?
どのように起こったのか知りたいです、ありがとうございました!

+2

あなたはあなたの足を撃って、「何かが間違っているのはなぜですか?」と尋ねます。まず、一時的な文字列のアドレスを保存します。これは本当に悪いことです。第二に、resetを呼び出すのではなく、shared_ptrにNULLを代入します。 – ForEveR

+0

私はあなたが達成しようとしているか、あなたが求めていることを本当に知りません。私はあなたがポインタと彼らが指しているものとの違いをよりよく理解する必要があると思います。 –

+0

.... a = NULL; nullpointer –

答えて

7

std::shared_ptrの背後にあるすべての目的は、動的に割り当てられたオブジェクトの所有権を取得することです。 std::shared_ptrは、std::make_sharedを介して、またはポインタを直接割り当てることによって、動的に割り当てられたオブジェクトの所有権を取得すると、std::shared_ptrが所有し、ストックとバレルをロックします。所有しているということは、動的スコープのオブジェクトへの最後の参照が有効範囲外になったときに自動的にオブジェクトを動的にスコープすることを意味します。それはshared_ptrのためのもので、それ以外は何もありません。

a = NULL; 

これはshared_ptr所有のポインタ(*)を交換するshared_ptrの代入演算子を使用していました。 shared_ptrが所有する元の動的スコープオブジェクトは他の参照を持たないため、 deleteは、それを構築するために使用された元のポインタです。

intへの元のネイティブポインタがまだあるということは無関係です。 shared_ptrは気にしません。全体がdeleteになります。

あなたはshared_ptr何でもnewdeleteしたい、とのネイティブポインタを使用し、いずれかのshared_ptrを使用していない、または1つの周り限り、あなたはまだネイティブポインタを使用する必要があるとして残っていることを確認していない場合基礎となるオブジェクトに移動します。

(*)実際には暗黙的に別のshared_ptrを構成し、通常の代入演算子を使用します。

+0

ありがとう、私は非常に詳細、非常に明確な、私を助けてくれます。 –

+0

もう1つは、私が尋ねたいのは、これはAndroid :: sp(強力なポインタ)でも行われるのでしょうか? –

1

このコードは、G ++ 4.2.1でコンパイルされません(ただし、サムが述べたように、それはバージョン6に準拠しています):で

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp 
main.cpp:17:11: error: no viable overloaded '=' 
     a = NULL; // Free the shared pointer 
     ~^~~~~ 

ところで、あなたはshared_ptr::resetを使用する必要がありますそれ以外の場合、shared_ptrはpの所有権を のカウントで取得し、 - オプションでdelおよび/またはdeleterとしてallocを、 アロケータでそれぞれ所有権を取得します。その値が変更前の のshared_ptrのデストラクタが呼び出されたかのように

また、この関数の呼び出しは、同じ副作用を持っている(これのshared_ptrがユニークだった場合、管理対象オブジェクトの削除 を含みます)。


またstring::c_strを確認してください。一時的な文字列のアドレスを保存しています。一時的な文字列は、何か悪いことの始まりです。

+0

gcc 6.3.1でコンパイルしてください。 –

+0

@SamVarshavchik、素敵な答え! – gsamaras

関連する問題