首先,我真的检查了是否有问题已经被问过,但我找不到任何问题。错误消息不应该欺骗你我猜我的情况有点不同,或者我只是错过了一些东西。
当我处理一个玩具 C++ 代码时,我遇到了一个奇怪的错误。程序输出说有双重释放的情况,但我看不到这个错误发生的地方。代码可能有点长,对此我深表歉意。
我现在正在工作Linux Distribution
,我正在使用g++ 9.1.0
. 我检查了我的代码并寻找错误的部分。
即使我修复了部分代码,但我的问题并没有得到解决,除非我评论或者Foo{1, "Hello World"};
我vec.push_back(std::move(Foo{}));
不明白为什么。
class Foo
{
public:
Foo()
: val{nullptr}, str{nullptr}
{
std::cout << "You are in empty constructor\n";
}
Foo(int the_val, const char *the_str)
: val{new int}, str{new char[std::strlen(the_str + 1)]}
{
*val = the_val;
std::cout << *val << '\n';
std::strcpy(str, the_str);
std::cout << str << '\n';
}
~Foo()
{
if (val) {
delete val;
} else {
std::cout << "val is empty\n";
}
if (str) {
delete[] str;
} else {
std::cout << "str is empty\n";
}
}
Foo(const Foo&) = delete;
Foo& operator= (const Foo&) = delete;
Foo(Foo&& rhs)
{
std::cout << "Move constructor is triggered\n";
if (val) {
delete val;
}
val = rhs.val;
rhs.val = nullptr;
if (str) {
delete[] str;
}
str = rhs.str;
rhs.str = nullptr;
}
Foo& operator= (Foo& rhs)
{
std::cout << "Move assignment is triggered\n";
// Self-assignment detection
if (&rhs == this) {
return *this;
}
if (val) {
delete val;
}
val = rhs.val;
rhs.val = nullptr;
if (str) {
delete[] str;
}
str = rhs.str;
rhs.str = nullptr;
return *this;
}
private:
int *val;
char *str;
};
int main()
{
Foo{1, "Hello World"};
std::vector<Foo> vec;
vec.push_back(std::move(Foo{}));
return 0;
}
如果我不在函数 main 中的任何地方注释,输出如下。
1
Hello World
You are in empty constructor
val is empty
str is empty
You are in empty constructor
Move constructor is triggered
free(): double free detected in tcache 2
Aborted (core dumped)
如果我评论 "Foo{1, "Hello World"};",输出变为
You are in empty constructor
Move constructor is triggered
val is empty
str is empty
val is empty
str is empty
最后,当我评论“vec.push_back(std::move(Foo{}));”时,输出变为
You are in empty constructor
Move constructor is triggered
val is empty
str is empty
val is empty
str is empty