Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QVector<QString> reference count crashing



  • in a game i use Builder design pattern. The game has categories and each category has some properties associated with it (pictures, category name, category related file path):

    struct CategoryProperties {
    	QString m_propertyName;
    	QString m_wordsFilePath;
    	QVector<QString> m_iconPaths;
    };
    

    here's the base builder class:

    #include "categoryProperties.h"
    
    class PropertiesBuilder {
    public:
    	virtual ~PropertiesBuilder() = 0;
    
    	virtual void setPropertyName() = 0;
    	virtual void setWordsFilePath() = 0;
    	virtual void setIconPaths() = 0;
    
    	CategoryProperties *getPropertiesPtr() const { return m_properties; }
    
    protected:
    	CategoryProperties *m_properties;
    };
    
    inline PropertiesBuilder::~PropertiesBuilder() {}
    

    and this is one of its derived classes:

    // .h
    #include "propertiesBuilder.h"
    
    class MapBuilder : public PropertiesBuilder {
    public:
    	MapBuilder();
    	~MapBuilder() override;
    
    	void setPropertyName() override;
    	void setWordsFilePath() override;
    	void setIconPaths() override;
    };
    
    // .cpp
    #include "mapBuilder.h"
    #include "propertiesBuilder.h"
    #include "categoryProperties.h"
    
    MapBuilder::MapBuilder() {
    	m_properties = new CategoryProperties;
    }
    
    MapBuilder::~MapBuilder() {
    	delete m_properties;
    }
    
    void MapBuilder::setPropertyName() {
    	m_properties->m_propertyName = "map";
    }
    
    void MapBuilder::setWordsFilePath() {
    	m_properties->m_wordsFilePath = "words/geography.txt";
    }
    
    void MapBuilder::setIconPaths() {
    	m_properties->m_iconPaths.reserve(6);
    	for(auto i = 0; i < 6; ++i)
    		m_properties->m_iconPaths.push_back(":/map/map_" + QString::number(i));
    }
    

    then i have a widget (which is the Director of Builder pattern), where i have buttons - one for each category:

    class CategoriesPage : public QWidget {
    	Q_OBJECT
    public:
            // ...
    private slots:
    	void onMapBtnClicked();
    private:
    	// category page properties
    	PropertiesBuilder *m_pPropBuilder;
    	CategoryProperties *m_pCategoryProps;
    };
    
    // Map button
    const auto mapBtn = new CategoryButton { ":/map/map_0", "Geography", sMapToolTip, this };
    connect(mapBtn, &QAbstractButton::clicked, this, &CategoriesPage::onMapBtnClicked);
    

    the slot:

    void CategoriesPage::onMapBtnClicked() {
    	if(m_pPropBuilder) delete m_pPropBuilder;
    	//if(m_pCategoryProps) delete m_pCategoryProps;
    	m_pPropBuilder = new MapBuilder;
    	setCategoryProperties();
    	m_pCategoryProps = dynamic_cast<MapBuilder *>(m_pPropBuilder)->getPropertiesPtr();
    }
    

    the slots for other categories are similar.

    now, the problem is, when a button is clicked, everything is okay. the category is properly set up. but when i click another button, the program crashes. i debugged and saw that the problem was this:

    if i delete m_pCategoryProps (last code snippet, commented), i get a crash on QVector, where there's something wrong with reference count (see the struct). when i commented the line, everything is okay. but there's a memory leak so it's not okay.

    i've spent quite a lot time on this and couldn't figure out anything.
    can someone please explain what am i doing wrong?

    thanks a lot.


  • Lifetime Qt Champion

    Hi,

    You are deleting your m_pPropBuilder which deletes its m_properties that you stored in m_pCategoryProps then you delete m_pCategoryProps so basically you are trying to delete again something that was already deleted.


Log in to reply