繁体   English   中英

unique_ptr 的分段错误

[英]Segmentation fault with unique_ptr

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

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 如何很好地解决它。

有任何想法吗?

问题如下

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.
}

您提供的代码可以编译并运行良好-因此您未提供的部分肯定存在问题-我怀疑Add()中的代码或其返回类型,或者稍后使用指针,因为怀疑是ecktschnagge 工作示例在 gdbonline 上:
https://onlinegdb.com/r1oyXGK2S

by use of std::unique_ptr .首先我问一个问题,通过使用std::unique_ptr获得什么优势。 考虑到唯一指针并不能保证有一个指针 - 在Add()内你必须检查nullptr ,我认为从你的用法来看,你不想使用std::unique_ptr

关键是,一个std::unique_ptr只有一个唯一的所有权。 其中之一:

  • func() ::本地 scope
  • album::Add() ::parameter_scope

拥有它。

由于您没有使用std::move()所有权保留在func()中,并将在 func( func()结束时被销毁。 为避免这种情况,您不妨使用song.release() (请参阅cpp-reference )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM