我试图使用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如何很好地解决它。
有什么想法吗?
答案 0 :(得分:1)
问题如下
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.
}
答案 1 :(得分:1)
您提供的代码可以编译并正常运行-因此,您未提供的部分肯定存在问题-我怀疑Add()
中的代码或其返回类型,或者以后将指针用作{{3}怀疑。工作示例在gdbonline上:
necktschnagge
首先,我问一个问题,您想通过使用std::unique_ptr
获得的优势?考虑到唯一指针并不能保证有一个指针-在Add()
内,您必须检查nullptr
!
我认为从您的用法来看,您不想使用std::unique_ptr
:
关键在于,std::unique_ptr
仅具有唯一所有权。其中之一:
func()
::本地范围album::Add()
:: parameter_scope 拥有它。
由于您未使用std::move()
,因此所有权保留在func()
中,并且将在func()
的末尾被销毁。为避免这种情况,您最好使用song.release()
(请参见https://onlinegdb.com/r1oyXGK2S)。