c++ 具有unique_ptr的分段错误

soat7uwm  于 2022-11-19  发布在  其他
关注(0)|答案(2)|浏览(224)

我尝试使用unique_ptr而不是自己分配内存。我有以下代码:

class Album {
...
public:
    Add(Song* song);
...
}

void func(){
    ...
    std::unique_ptr<Album> album = std::unique_ptr<Album>{new Album()};
    std::unique_ptr<Song> song = std::unique_ptr<Song>{new Song(soundtrack.data(), soundtrack.length())};
    album->Add(song.get());
    ...
}

我得到的分割错误为:

album->Add(song.get());

我尝试了多种变体来获取指针,包括std::move和make_unique,但也许我不明白unique_ptr是如何工作得足够好来解决这个问题的。
有什么想法吗?

ldfqzlk8

ldfqzlk81#

您提供的代码编译和运行良好-因此您没有提供的部分一定有问题-我怀疑代码在Add()或它的returntype中,或者稍后使用指针作为necktschnagge。工作示例在gdbonline上:
https://onlinegdb.com/r1oyXGK2S
首先我问一个问题,what is the advantage you'll like to achive通过使用std::unique_ptr。考虑到一个唯一指针并不保证有一个指针对象-在Add()中,你必须检查nullptr!我认为从你的用法来看,你不想使用std::unique_ptr
关键是,std::unique_ptr只有唯一的所有权。

  • func()::局部作用域
  • album::Add()::参数范围

拥有它。
因为你没有使用std::move(),所以所有权仍然在func()中,并且将在func()结束时被销毁。为了避免这种情况,你还可以使用song.release()(参见cpp-reference)。

jdgnovmf

jdgnovmf2#

问题如下

class Album {
...
public:
    Add(Song* song);
...
}

void func(){
    ...
    std::unique_ptr<Album> album = std::unique_ptr<Album>{new Album()};
    std::unique_ptr<Song> song = std::unique_ptr<Song>{new Song(soundtrack.data(), soundtrack.length())};
    album->Add(song.get());
    ...
    // Here the object song gets destructed. This means that the underlying Song gets destructed.
    // So right after leaving func() the pointer that was returned by song.get() now points to non-allocated memory containing random bits at worst case.
}

所以一个可能的解决方案是...

class Album {
...
public:
    Add(std::unique_ptr<Song> song); // you still need to move song inside Add(...)
...
}

void func(){
    ...
    std::unique_ptr<Album> album = std::unique_ptr<Album>{new Album()};
    std::unique_ptr<Song> song = std::unique_ptr<Song>{new Song(soundtrack.data(), soundtrack.length())};
    album->Add(std::move(song)); //here song is intended  to be moved inside Add(...)
    ...
    // If moved inside Add(...) song points to nullptr here.
}

相关问题