Can't find the invalid pointer
-
I'm working with qt5.15 in qtCreator in ubuntu 20.04 and g++. My program compiles and works fine until I close the main window becuase I get the error in the title of the question. I read that this error occurs when there is a invalid pointer, I tried to find it in my program but I couldnt.
main.cpp
#include "MainWindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
MainWindow.h
#pragma once #include "Facelet.h" #include "Face.h" #include <QMainWindow> #include <QWidget> #include <QSpacerItem> class MainWindow : public QMainWindow { Q_OBJECT using type = Face; public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); protected: virtual void resizeEvent(QResizeEvent*) override; private: void __init_spacers(); QWidget* wid; type* object; QGridLayout* layout; QSpacerItem* spacer; };
MainWindow.cpp
#include "MainWindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { object = new type(); layout = new QGridLayout(); wid = new QWidget(); __init_spacers(); layout->setContentsMargins(0,0,0,0); layout->addWidget(object, 1, 1); wid->setLayout(layout); setCentralWidget(wid); } MainWindow::~MainWindow() { delete spacer; delete object; delete layout; delete wid; } //protected void MainWindow::resizeEvent(QResizeEvent*) { int side = (size().width() < size().height()) ? size().width() : size().height(); object->resize(side, side); } //private void MainWindow::__init_spacers() { spacer = new QSpacerItem(0,0, QSizePolicy::Expanding, QSizePolicy::Expanding); layout->addItem(spacer, 0, 1);//top layout->addItem(spacer, 1, 0);//left layout->addItem(spacer, 2, 1);//bootom layout->addItem(spacer, 1, 2);//right }
Face.h
#pragma once #include "Facelet.h" #include <QGridLayout> class Face : public QWidget { Q_OBJECT public: explicit Face(QWidget* parent = nullptr); ~Face(); std::string get_pattern(); protected: virtual void resizeEvent(QResizeEvent *event = nullptr) override; private: void __init_widget(); void __init_layout(); void __init_facelets(); void __update_facelets(int side); void __delete_facelets(); Facelet** facelets; QGridLayout* layout; constexpr static unsigned int SIDE = 248; constexpr static unsigned int SPACE = 10; };
Face.cpp
#include "Face.h" Face::Face(QWidget* parent) : QWidget(parent) { __init_facelets(); __update_facelets(75); __init_layout(); __init_widget(); } Face::~Face() { __delete_facelets(); delete layout; } std::string Face::get_pattern() { std::string result; for(int i = 0; i < 3; ++i) { for(int j = 0; j < 3; ++j) { result.push_back( char(Colors::list[facelets[i][j].id()].second) ); } } return result; } //protected void Face::resizeEvent(QResizeEvent *event) { int side = (size().width() > size().height()) ? size().width() : size().height(); int facelet_side = (side-8)/3; __update_facelets(facelet_side); } //private void Face::__init_widget() { this->resize(SIDE, SIDE); this->setMinimumSize(SIDE, SIDE); this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); this->setAttribute(Qt::WA_StyledBackground); this->setStyleSheet("background-color: black;"); this->setLayout(layout); } void Face::__init_layout() { layout = new QGridLayout(); layout->setSpacing(2); layout->setContentsMargins(2, 2, 2, 2); for(int i = 0; i < 3; ++i) { for(int j = 0; j < 3; ++j) { layout->addWidget(&facelets[i][j], i, j); } } } void Face::__init_facelets() { facelets = new Facelet*[3]; for(int i = 0; i < 3; ++i) { facelets[i] = new Facelet[3]; } } void Face::__update_facelets(int side) { for(int i = 0; i < 3;++ i) { for(int j = 0; j < 3; ++j) { facelets[i][j].setFixedSize(side, side); } } } void Face::__delete_facelets() { for(int i = 0; i < 3; ++i) { delete[] facelets[i]; } delete[] facelets; }
Facelette.h
#pragma once #include "Colors.h" #include <QPushButton> #include <QPainter> class Facelet : public QPushButton { Q_OBJECT public: using id_type = Colors::Id; explicit Facelet(QWidget* parent = nullptr); explicit Facelet(Colors::Id color, QWidget* parent = nullptr); virtual ~Facelet(); void reset(); void set_color(Colors::Id); id_type id(); protected: virtual void paintEvent(QPaintEvent *e = nullptr) override; public slots: void __change_color(); private: int _Id; };
Facelet.cpp
#include "Facelet.h" #include <QStyleOption> Facelet::Facelet(QWidget* parent) : QPushButton(parent) { reset(); connect(this, SIGNAL(clicked()), SLOT(__change_color())); } Facelet::Facelet(Colors::Id id_, QWidget* parent) : QPushButton(parent) { set_color(id_); connect(this, SIGNAL(clicked()), SLOT(__change_color())); } Facelet::~Facelet() {} void Facelet::reset() { _Id = -1; this->setStyleSheet("background-color:lightGray;"); } void Facelet::set_color(Colors::Id _id) { _Id = _id; setStyleSheet(QString("background-color:")+Colors::list[_Id].first+";"); } Facelet::id_type Facelet::id() { return Facelet::id_type(_Id); } //protected void Facelet::paintEvent(QPaintEvent *) { QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } //private slots void Facelet::__change_color() { _Id = (_Id >= 5) ? 0 : (_Id+1); set_color(Colors::Id(_Id)); }
Colors.h
#pragma once #include "Rubix/Rubix.h" #include <array> #include <utility> #include <QColor> struct Colors { using value_type = typename std::pair<QString, rbx::RColor>; using array_type = typename std::array<value_type, 6>; enum Id { Yellow, Red, Green, Orange, Blue, White }; static array_type list; };
Colors.cpp
#include "Colors.h" Colors::array_type Colors::list = { Colors::value_type("yellow", rbx::YELLOW), Colors::value_type("rgb(255, 20, 20)", rbx::RED), Colors::value_type("rgb(35, 255, 35)", rbx::GREEN), Colors::value_type("rgb(255, 130, 20)", rbx::ORANGE), Colors::value_type("blue", rbx::BLUE), Colors::value_type("white", rbx::WHITE), };
when I close the window I get the following error
21:07:22: Starting /home/kubuntu/Desktop/projects/x64/RubbixSolver/Debug/GUI/build-GUI-Desktop_Qt_5_15_2_GCC_64bit-Profile/GUI ... 21:07:46: The program has unexpectedly finished. 21:07:46: The process was ended forcefully. 21:07:46: /home/kubuntu/Desktop/projects/x64/RubbixSolver/Debug/GUI/build-GUI-Desktop_Qt_5_15_2_GCC_64bit-Profile/GUI crashed.
If I start the debug when I close the main window it says there is a problem in Face::~Face(), a small message-window pops up with the following message'
The inferior stopped because it received a signal from the operating system. Signal name : SIGSEGV Signal meaning : Segmentation fault
, the conosle debug displays a bounch of ```
RTTI symbol not found for class 'QObject' -
@Gallo-Magico said in Can't find the invalid pointer:
void Face::__delete_facelets() {
for(int i = 0; i < 3; ++i) {
delete[] facelets[i];
}
delete[] facelets;
}@Gallo-Magico I feel in destructor you are doing double deletion.
deleting the memory which was already deleted.delete[] facelets; //comment it out
-
void Face::__init_layout() { .... layout->addWidget(&facelets[i][j], i, j); }
You have added the facelets objects to the layout.
The ownership of item is transferred to the layout, and it's the layout's responsibility to delete it.
I feel no need to free the memory in the destructor for the facelets and as well as layout.Refer object tree & ownership details
https://doc.qt.io/qt-5/objecttrees.html -
@nagesh I still get error but is a different message
The inferior stopped because it received a signal from the operating system. Signal name : SIGABRT Signal meaning : Aborted
I get this error in
Facelet::~Facelet()
and the console application displaysmunmap_chunk(): invalid pointer
.
I also tried to turnfacelets
into aFacelet***
and treatFacelet[i][j]
as a pointer instead as an object, but I get the same error I got at the begin -
@Gallo-Magico do you still get these errors when you are not deleting/freeing?
//__delete_facelets(); //delete layout;
-
@Gallo-Magico said in Can't find the invalid pointer:
MainWindow::~MainWindow()
{
delete spacer;
delete object;
delete layout;
delete wid;
}Same problem here. If
QObject
s have a parent they get deleted when the parent gets deleted automatically, if you do it manually it's a double deletion.
If debugging is becoming a mess change the type of yourQObject
s pointer toQPointer
so the pointers will be set to null automatically on deletion and you won't be able to double-delete them -
@VRonin said in Can't find the invalid pointer:
Same problem here. If QObjects have a parent they get deleted when the parent gets deleted automatically, if you do it manually it's a double deletion.
No it is not. The child notifies the parent when it goes away, so the parent detaches it from the list.
-
@kshegunov said in Can't find the invalid pointer:
No it is not. The child notifies the parent when it goes away, so the parent detaches it from the list.
@VRonin forgot a sentence in
if you do it manually it's a double deletion.
- if you do it manually after the parent deleted it's children it's a double deletion :) -
I figured out,there were a bounch of problem, first of all I used to double delete child widgets, like the layout(child of the main widget) and the other widget into the layout(child of the layout), then I got all my destructors empty but I got an error caused by deleting a location memory not allocated with new. In my case the dynamic matrix of facelet don't allocate the memory for each Facelet, then I turned facelets from
Facelet** facelets
into aFacelet*** facelets
and changedinit_facelets()
tovoid Face::init_facelets() { facelets = new Facelet**[3]; for(int i = 0; i < 3; ++i) { facelets[i] = new Facelet*[3]; for(int j = 0; j < 3; ++j) { facelets[i][j] = new Facelet(); } } }
When the program ends,
Face::~Face()
frees all the location corresponding tofacelets[i][j]
, then I had to free the rest of the matrix, so nowFace::~Face()
looks likeFace::~Face() { for(int i = 0; i < 3; ++i) { delete[] facelets[i]; } delete[] facelets; }
Now it works with no problem or any issue
-
@Gallo-Magico said in Can't find the invalid pointer:
layout->addWidget(&facelets[i][j]
This sets
Face
as parent offacelets[i][j]
so same error as before you are double deleting aQObject
as the parent already deleted itNo it is not. The child notifies the parent when it goes away, so the parent detaches it from the list.
Good observation, I didn't explain myself well there.
P.S.
from https://en.cppreference.com/w/cpp/keyword- identifiers with a double underscore anywhere are reserved
- identifiers that begin with an underscore followed by an uppercase letter are reserved
You should rename your methods/members