C++ 类析构函数SEGFAULT
在我的项目中,我有两个类,C++ 类析构函数SEGFAULT,c++,segmentation-fault,destructor,delete-operator,C++,Segmentation Fault,Destructor,Delete Operator,在我的项目中,我有两个类,EarleyParser类: class EarleyParser { public: EarleyParser(); virtual ~EarleyParser(); void initialize( string filePath, bool probabilityParse ); private: bool probabilityParser; typede
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;
};
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_映射
和列表
会被填充,但是调用EarleyParser的标准析构函数类
时会出现分段错误
据我所知,EarleyParser
的默认析构函数应该调用unordered_map
的默认析构函数,该析构函数应该调用列表中的一个
,该列表应该为其每个元素调用Production
类的默认析构函数,如下所示:
Production::~Production()
{
if( this->productionContent != NULL )
delete this->productionContent; <- line 44
}
有两种选择
您可以在生产中动态分配向量,在这种情况下,您需要一个赋值运算符来执行向量指针的深度复制。复制构造函数也应该这样做。在这种情况下,您应该遵循以下步骤
或者,您在Production
构造函数中获取指向向量的指针,并且不执行深度复制,在这种情况下Production
不拥有向量,不应在析构函数中删除它
如果您有案例1,我建议您放下指针并按值按住std::vector
。您的三个规则不完整。因为您有一个指针成员,所以需要确保已经实现了复制构造函数、复制赋值运算符和析构函数
现在,因为您有一个指向vector
成员的指针,我要告诉您不应该有这个,而应该有一个std::vector
或一个std::unique\u ptr
我不知道为什么您决定需要保存指向容器的指针,但这绝不是一个好理由,而且很容易出错
您可以保存对容器的引用,但需要确保它已在ctor中初始化
指针的问题在于,它们太容易被当作“解决方案”,但实际上极易出错,很难使用。如果您不再考虑指针,也不再倾向于在每一个转折点都使用它们,那么您的工作就会轻松得多。我没有看到productionContent变量的任何初始化。尝试使用初始值设定项将其初始化为NULL。未初始化成员变量的默认值不为null
这意味着productionContent!=NULL将始终为true,因为它开始时不是NULL
在所有构造函数中尝试以下操作:
Production::Production( const Production& copy_me ) : productionContent(NULL)
{
...
对于指针的任何好的或坏的理由,请使用std::shared_ptr(作为成员和构造函数参数),做得越少,做得越多。std::shared_ptr将为您创建空ptr和删除 在复制构造函数中,是复制指针还是进行“深度”复制?为什么有一个指向容器的指针?为什么不改为引用呢?Production
的复制构造函数是什么样子的,为什么析构函数是虚拟的?另外,Production
是否拥有vector
?如果是,为什么它是指针;如果不是,为什么要删除它?vector*getProductionContent()这让我恶心。Urgh指向容器的指针。@Xeo-I添加了副本constructor@TonyTheLion-我用这个选项编译,所以我相信是的。。。
Production::Production( const Production& copy_me ) : productionContent(NULL)
{
...