类析构函数 SEGFAULT



在我的项目中,我有两个类,EarleyParser类:

class EarleyParser
{
public:
EarleyParser();
virtual ~EarleyParser();
void initialize( string filePath, bool probabilityParse );
private:
bool probabilityParser;
typedef unordered_map< string, list<Production> > productionHashTable;
productionHashTable earlyHashTable;
};

Production类:

class Production
{
public:
Production();
Production( float productionProbability, int productionLength, vector< string >* productionContent );
Production( const Production& copy_me );
virtual ~Production();
float getProductionProbability();
int getProductionLength();
vector< string >* getProductionContent();
private:
float productionProbability;
int productionLength;
vector< string >* productionContent;
void setProductionProbability( float productionProbability );
void setProductionLength( int productionLength );
void setProductionContent( vector< string >* productionContent );
};

正如你在上面看到的,EarlyParser类有一个成员元素,它是一个unordered_map,其关键元素是一个字符串,值是Production类中元素的list

代码工作正常,unordered_maplist被填充,但是在调用EarleyParser的标准析构函数类时,我得到了分段错误。

据我了解,EarleyParser的默认析构函数应该调用unordered_map的默认析构函数,该析构函数应该调用list之一,该应为其每个元素调用Production类的默认析构函数,如下所示:

Production::~Production()
{
if( this->productionContent != NULL )
delete this->productionContent; <- line 44
}

使用 Valgrind 和 GDB 进行回溯跟踪并没有给我太多关于如何解决分段错误的帮助,这在析构函数第 44 行的EarleyParser.cpp中给出

。我应该实现析构函数类,还是默认析构函数没问题? 关于可能导致分段错误的原因的任何想法?

添加了复制构造函数

Production::Production( const Production& copy_me )
{
if( this->productionContent != NULL )
this->productionContent = NULL;
this->setProductionProbability( copy_me.productionProbability );
this->setProductionLength( copy_me.productionLength );
this->setProductionContent( copy_me.productionContent );
}

你的三法则不完整。由于您有一个指针成员,因此您希望确保已实现复制构造函数、复制赋值运算符析构函数

现在,因为你有一个指向vector成员的指针,所以我要告诉你,你不应该有它,而只是有一个std::vector<std::string>或一个std::unique_ptr<std::vector<std::string> >

我不知道你为什么决定需要持有指向容器的指针,但这主要不是一个很好的理由,而且容易出错。

您可以保存对容器的引用,但需要确保它在 ctor 中初始化。

指针的问题在于它们太容易被当作"解决方案",但实际上非常容易出错且难以使用。如果你不再考虑指针,不再倾向于动不动就使用它们,那么你就会更容易。

我没有看到生产内容变量的任何初始化。 尝试使用初始值设定项将其初始化为 NULL。 未初始化成员变量的默认值不为 null。

这意味着 productionContent != NULL 将始终为真,因为它一开始不是 NULL。

在所有构造函数中尝试类似的东西:

Production::Production( const Production& copy_me ) : productionContent(NULL)
{
...

有两个选项。

  1. 要么在Production中动态分配向量,在这种情况下,您需要赋值运算符来执行向量指针的深层复制。复制构造函数也应该这样做。在这种情况下,您应该遵循三法则。

  2. 或者,在Production构造函数中获取指向矢量的指针,并且不执行深层复制,在这种情况下,Production不拥有该矢量,不应在析构函数中删除它。

如果您有情况 1,我建议删除指针并按值按住std::vector

对于指针的任何好或坏的理由,请使用 std::shared_ptr(作为成员和构造函数参数),您做的越少,您就越多。 std::shared_ptr 将为您制作 nullptr 和删除!

相关内容

  • 没有找到相关文章

最新更新