gpt4 book ai didi

c++ - 免费(): double free detected in tcache 2 in C++

转载 作者:太空狗 更新时间:2023-10-29 20:49:33 25 4
gpt4 key购买 nike

首先,我真的检查了是否有已经提出的问题,但我找不到任何问题。错误消息不应欺骗您,我猜我的情况有点不同,或者我只是遗漏了一些东西。

当我处理一个玩具 C++ 代码时,我遇到了一个奇怪的错误。程序输出说有double free的情况,但是我看不到这个错误发生的地方。代码可能有点长,请见谅。

我现在正在开发一个 Linux 发行版,我正在使用 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

最佳答案

对于初学者来说,这个构造函数使用了错误的内存初始化器

Foo(int the_val, const char *the_str)
: val{new int}, str{new char[std::strlen(the_str + 1)]}
^^^^^^^^^^^

我想你的意思是

Foo(int the_val, const char *the_str)
: val{new int}, str{new char[std::strlen(the_str ) + 1]}

这个移动构造函数也是无效的

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

在构造函数的主体中,数据成员 valstr 具有不确定的值。当构造函数的主体获得控制权时,它们没有被初始化。

可以这样写

Foo(Foo&& rhs) : val( nullptr ), str( nullptr )
{
std::cout << "Move constructor is triggered\n";

std::swap( val, rhs.val );
std::swap( str, rhs.str );
}

这个运算符

Foo& operator= (Foo& rhs)

不是移动赋值运算符。它是一个复制赋值运算符。所以它的定义是错误的。

还有这条主线

Foo{1, "Hello World"};

没有意义。对象被创建并立即被删除。

在这个声明中

vec.push_back(std::move(Foo{}));

std::move 是多余的,因为 Foo{} 已经是一个右值。

关于c++ - 免费(): double free detected in tcache 2 in C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58039538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com