Cory Klein
Cory Klein

Reputation: 55610

Heap overrun error is resolved by removing a heap allocated variable?

While investigating a glibc crash I get this valgrind error:

Invalid write of size 8
   at 0x43A3D2: DataAudit::DataAudit(DataAuditModel*, QWidget*) (DataAudit.cpp:15)
   by 0x42D318: MainWindow::createNewDataAudit(DataAuditModel*) (MainWindow.cpp:191)
   by 0x48CA09: MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (moc_MainWindow.cpp:65)

Invalid write of size 8 seems to indicate a heap block overrun.

Here are the two problem classes, pared down for conciseness:

class IAWidgetModelOwner : public IAWidget
{
public:
    explicit IAWidgetModelOwner(IAWidgetModel *model, QWidget *parent = 0) :
        IAWidget(model, parent),
        pointer1(MAIN_WINDOW),
        pointer2(MAIN_WINDOW) // See note below
        { }

private:
    MainWindow *pointer1;
    MainWindow *pointer2;  // See note below
};

class DataAudit : public IAWidgetModelOwner, public Ui::DataAudit
{
public:
    explicit DataAudit(DataAuditModel *dataAuditModel, QWidget *parent = 0) :
    IAWidgetModelOwner(dataAuditModel, parent),
    _dataAuditModel(dataAuditModel) // DataAudit.cpp:15
    { ... }
    ...

private:
    QList<RawLog*> _rawLogs;
    DataAuditModel *_dataAuditModel;
};

The puzzling thing, is that the valgrind error does not appear if I remove pointer2 from IAWidgetModelOwner by commenting out the indicated lines above. Removing all references to _dataAuditModel also resolves the error.

Since I am not actually calling new or malloc in this class, I don't understand how the automatic heap allocation could cause such an error. I feel like I'm at a dead end in investigating this bug.

What am I doing wrong, or where is a good place to look next?

Note: MAIN_WINDOW is a globally defined MainWindow pointer pulled in from Globals.h

Upvotes: 1

Views: 2255

Answers (2)

Cory Klein
Cory Klein

Reputation: 55610

Surprise surprise, the actual error was in code that I chose not to include:

class IAWidgetModelOwner : public IAWidget
{
    Q_OBJECT
public:

I used the Q_OBJECT macro, but it had no signal or slot declarations. Either of the following solved my problem:

  1. Remove Q_OBJECT
  2. Define a slot public slot: mySlot() {}

In reality, I thought I had declared one of the member functions as a slot.

Upvotes: 0

jxh
jxh

Reputation: 70362

Somehow,MainWindow::createNewDataAudit() is not allocating an object large enough for your DataAudit object. Focus your debugging efforts there.

Since not enough memory is allocated, initializing the pointer member _dataAuditModel causes the overrun. When you remove the member pointer2 from the base class, you are shrinking the size of the DataAudit object to fit in the memory allotted to it by MainWindow::createNewDataAudit().

Upvotes: 1

Related Questions