gpt4 book ai didi

C++ 为什么在 vector 段错误中放置对象?

转载 作者:行者123 更新时间:2023-11-30 01:34:53 25 4
gpt4 key购买 nike

我想创建一个“Act”对象 vector ,其中包含指向“Eat”或“Drink”动态分配对象的指针。新对象是这样放置的:

action_vector.emplace_back(Act::BehaviorType::eat);

但是,这是段错误,我不明白为什么。我认为 emplace_back 会隐式调用移动构造函数,而不是析构函数,但出于某种原因,它(我认为)是搞砸一切的原因。

有什么方法可以成功创建此类对象的 vector 吗?

这是其余代码及其输出。对不起,如果它有点冗长,但基本上它只是一种策略模式。

#include <iostream>
#include <vector>

class IBehavior
{
public:
IBehavior() = default;
virtual ~IBehavior() = default;
virtual void execute() = 0;
};

class Drink : public IBehavior
{
public:
Drink(): IBehavior() {}
~Drink() {}
void execute() { std::cout << "Drinking" << std::endl; }
};

class Eat : public IBehavior
{
public:
Eat(): IBehavior() {}
~Eat() {}
void execute() { std::cout << "Eating" << std::endl; }
};


class Act
{
IBehavior * b;

public:

enum class BehaviorType { eat = 0, drink = 1 };

Act() = default;
~Act()
{
std::cout << "Calling the destructor" << std::endl;
delete b;
}
Act(BehaviorType b_type) { SetBehavior(b_type); }

Act(Act&& act)
{
std::cout << "Calling the move constructor" << std::endl;
this->b = act.b;
}


void SetBehavior(BehaviorType b_type)
{
if(b_type == BehaviorType::eat) b = new Eat();
if(b_type == BehaviorType::drink) b = new Drink();
}

void execute() { b->execute(); }
};


int main(int argc, char * argv[])
{
std::vector<Act> action_vector;

for(int i = 0; i < 10; ++i)
{
action_vector.emplace_back(Act::BehaviorType::eat);
action_vector[i].execute();
}

return 0;
}

输出:

Eating
Calling the move constructor
Calling the destructor
Eating
Calling the move constructor
Calling the move constructor
Calling the destructor
Calling the destructor
Segmentation fault: 11

最佳答案

你的移动构造函数复制b,而析构函数删除b,所以如果你移动构造一个实例,那么相同的指针值将被删除两次,这具有未定义的行为。

一般解决方案:使用智能指针。


另一个错误:默认构造函数使 b 未初始化。当默认构造的对象被销毁时,未初始化的指针被删除并且行为未定义。智能指针也解决了这个问题。

关于C++ 为什么在 vector 段错误中放置对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55368498/

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