2017-05-12 2 views
0

を格納された配列を反復することはできません、私は次のコードがあるとします。はスマートポインタで

std::shared_ptr<char*> getString() 
{ 
    char hello[] = {'h','e','l','l','o'}; 

    return std::make_shared<char*>(hello); 

} 

int main() 
{ 

    std::shared_ptr<char*> shared_str = getString(); 
    std::cout<< (*shared_str)<<std::endl;//OK 
    std::cout<<(*shared_str)<<std::endl;//KO 


    return 0; 
} 

私は最初の印刷を取得し、なぜ第二にエラーがある一方で、私は、知りません。同じ理由で、私は次のようなスマートポインタを反復処理することはできません。

for(int i = 0; i < 5; i++) 
std::cout<<(*shared_str)[i]; 

をこの場合にも、単に文字「H」が印刷されるので。 私はスマートポインタについて本当に混乱しています。その多くは、参照されるオブジェクトのライフタイムの処理に関するものであるため、あまり見つけられませんでした。

要約: "hello"配列が範囲外になり、実際にはmake_sharedがchar *のために動的にメモリを割り当て、 "hello"ポインタ内に格納するためエラーが発生しますが、配列そのものは関数geString()は終了します。

+6

あなたはローカル変数へのポインタを共有していることはできません。 'shared_ptr'が管理するものは' new'で割り振られなければなりません。 –

+0

"なぜ私はちょうど最初の印刷を取得し、2番目のものは間違っているのかわかりません" ... arent全く同じですか? 'std :: cout <<(* shared_str)<< std :: endl; // OK'と' std :: cout <<(* shared_str)<< std :: endl; // KO'私が見る唯一の違いスペースとコメントです.... – user463035818

+3

未定義の動作はそうです。時にはうまくいくように見えて、明らかに他の時には失敗します。要点は、コードが複数回実行された場合に変化する動作を含め、すべての動作が許可されていることです。 – Peter

答えて

3

コードに未定義の動作があります。

return std::make_shared<char*>(hello); 

返す共有ポインタにhelloを割り当てますが、これは返された後に存在しないローカル配列です。 また、shared_ptrは参照カウントが別のUBであるゼロに達すると、このポインタを削除します。

最も簡単な解決策はSTDを使用することです::文字列:

std::shared_ptr<std::string> getString() 
{ 
    char hello[] = {'h','e','l','l','o', '\0'}; 
    return std::make_shared<std::string>(hello); 
} 
+1

まだUBです: 'hello'はヌルで終了していないので' char * 'コンストラクターは最後を最後まで読み込みます。 – Quentin

+0

@クエンティン、ありがとう、それは3番目のUBでした。 – marcinj

+0

なぜ、 'return std :: make_shared (" hello ");' – NathanOliver

関連する問題