1

modify_entry次のコードは、型のオブジェクトへのポインターを関数に渡し、関数Entryの本体内でunique_ptr生のポインターを採用します。ただし、ポインターが指すオブジェクトは、関数が戻った後も存続しているように見えます。

このコードをコンパイルすると

#include <iostream>
#include <memory>

struct Entry {
    
    Entry(std::string name) : name_(name) { std::cout << "Constructor for " + name_ + '\n'; }
    ~Entry() { std::cout << "Destructor for " + name_ + '\n'; }
    std::string name_;
    
};

void modify_entry(Entry* e_ptr){
    
    std::cout << "Inside modify_entry()\n";
    std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";

}

int main(int argc, const char * argv[])
{
        
    Entry* entry_ptr = new Entry("John");
    modify_entry(entry_ptr);
    std::cout << "Back from modify_entry()\n";
    std::cout << entry_ptr->name_ << '\n';      // <---- line 25
            
    return 0;
    
}

clang バージョン 3.4 (タグ/RELEASE_34/final)

ターゲット: x86_64-apple-darwin13.1.0

スレッドモデル: posix

エラーなしで実行され、出力は

John のコンストラクタ

modify_entry() の内部

John Doe のデストラクタ

modify_entry() から戻る

ジョン・ドウ

ただし、ここでは、25 行目で実行時エラーが発生します。

Q: clang によって生成された実行可能ファイルを実行してもランタイム エラーが発生しないのはなぜですか?

誰かが状況を明確にしていただければ幸いです。所有権を適切に譲渡しようとしているわけではないことに注意してください。この不自然な悪いコードの例は、デバッグ プロセスの副産物です。make_uniqueなどの移動セマンティクスunique_ptrは素晴らしいですが、これは私が求めているものではありません。

前もって感謝します。

4

3 に答える 3

6

Q: clang によって生成された実行可能ファイルを実行してもランタイム エラーが発生しないのはなぜですか?

未定義の動作は未定義であるためです。プログラムは、有効期間が終了した後でオブジェクトにアクセスしようとします。C++ では、そのようなプログラムの動作は定義されていません。

make_uniqueなどの移動セマンティクスunique_ptrは優れています。このようなものは、使用する必要があるもう 1 つの理由です。

于 2014-04-15T14:20:27.187 に答える
3

あなたがしていることはundefined behaviorであるため、main関数内で破壊されたオブジェクトへのポインターを使用する場合。

オブジェクトは破棄 (削除) されます、元の場所へのポインターがまだあります。このポインターを逆参照すると、未定義の動作が発生します。

于 2014-04-15T14:21:07.780 に答える