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

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

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().

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:
Remove Q_OBJECT
Define a slot public slot: mySlot() {}
In reality, I thought I had declared one of the member functions as a slot.

Related

Use of temporal constructors inside vector

I cam from programming in Java and I thought doing as here [my code] could work the definition of temporal constructors, but I am having problems the proper way of writing the code to just work.
PROBLEM: I want to add a Constructor of the class Coomunication for every port I find in a machine and save it into a vector:
ControlCommunication.cpp:
...
QVector<Comunication *> ports;
...
void ControlCommunication::checkPorts(){
qint16 vendorid = cuquito.getVendorID();
qint16 productid = cuquito.getProductID();
const QString blankString = "N/A";
for (const QSerialPortInfo &serialPortInfo : QSerialPortInfo::availablePorts()) {
Comunication com(serialPortInfo.portName());
addPort(com); // <- I do not know how to get this working well
}
}
ControlCommunication.h:
class ControlCommunication : public QObject
{
Q_OBJECT
public:
explicit ControlCommunication(QObject *parent = nullptr);
QVector<Comunication*> getComunicationPorts(){return comunicationports;}
void addPort(Comunication com);
...
Comunication.h:
#ifndef COMUNICATION_H
#define COMUNICATION_H
#include <QObject>
#include <QSerialPort>
#include <QMainWindow>
class Comunication:public QObject{
Q_OBJECT
public:
Comunication( QString serialPortName);
Comunication();
public:
public slots:
void openSerialPort();
void closeSerialPort();
void writeData(const QByteArray &data);
void readData(QByteArray &data);
void handleError(QSerialPort::SerialPortError error);
QString getPortName(){return portname;};
signals:
private:
QSerialPort *m_serial = nullptr;
QString portname;
};
#endif // COMUNICATION_H
The error I get is: call to implicitly-deleted copy constructor of 'Comunication'
comunication.h:8:20: note: copy constructor of 'Comunication' is implicitly deleted because base class 'QObject' has a deleted copy constructor
qobject.h:449:20: note: 'QObject' has been explicitly marked deleted here
controlcommunication.cpp:27:49: note: passing argument to parameter 'com' here
As I understand from the error message, I cannot call a constructor which is gonna be deleted in that function from other statements. How can i get this working?
The error you're getting mean you can't copy Communication. When you're passing com to addPort, you're making a copy of the object which will be passed to the function. But because you're inheriting a QObject you can't make copies of your objects. Which means you can't those objects by value. You can add pointers or (ideally) a reference to use objects.
But in your case, I don't think that's going to work easily, you seem to want a QVector<Communication*> which I'm assuming will be filled by addPort. But you're creating Communication in your loop which will be delted when it exists the loop, and so pointers to it won't work.
I don't have enough information, and I'm not versed with Qt, so please someone correct if I'm wrong, but I would suggest that you build Communication inside addPort and change QVector<Communication*> to QVector<Communication>.
My intuition would be that Communication doesn't need to inherit from QObject, but I could be wrong. But the data from your program should probably be separated from the Qt stuff, to make things easier to manage.
You are passing the Comunication object by value into the addPort function. This will try to create a copy of the object. But QObjects (and anything derived from QObject) are non-copyable. So you should change your function to take a pointer or reference instead.
Also, you probably need to allocate your objects on the heap because they will go out of scope, freeing any stack memory.
void addPort(Communication *com);
...
for (const QSerialPortInfo &serialPortInfo : QSerialPortInfo::availablePorts()) {
// Allocate on the heap
Comunication *com = new Comunication(serialPortInfo.portName());
// Pass pointer to addPort
addPort(com);
}

Defining a pointer randomly crashes the program

Defining a variable in a class causes a random crash during the execution of the application.
The crash does not appear in debug mode, it only happens in release build.
It also happens in various point of execution. I am outputing logs every now and then during execution, and they will differ from time to time.
The class in question is the middle one in the inheritance chain:
class Base
{
public:
virtual ~BaseClass() { }
// Quite a few virtual methods declared here.
};
class Middle : public Base
{
public:
virtual ~Middle() { }
protected:
Middle(const std::string& name)
: _name(name)
, _db(Context::DbInstance())
{
}
/**
* Commenting out any of the following crashes or does not.
*/
// CareTaker* _careTaker; // 4 bytes, crashes.
// void* dummy; // 4 bytes, crashes.
// int dummy; // 4 bytes, crashes.
// short dummy; // 2 bytes, crashes.
// class Dummy {}; // 1 bytes, does not crash.
// // 0 bytes, member removed, does not crash.
std::string _name;
// Crash also happens/does not if a variable described above put here.
Database& _db;
// But not if it is here. Variable of any size is OK here.
};
class Derived : public Middle
{
public:
Derived() : Middle("Foo") { }
virtual ~Derived() { }
// Some virtual methods from Base overriden here.
};
In a nutshell, if a variable of size 2 or more comes before Database& _db definition, the crashes will happen. If it comes afterwards, they will not.
How would I go about to try to solve the crash without having access to a debugger in this scenario?
EDIT:
The class is used in the initializer method run after a DLL is loaded. I cannot give more details than this, unfortunately.
int DllInitializer()
{
// Complex code.
DbPlugger::instance().addPlug(new Derived());
// Complex code.
}
You haven't provided a mcve , so this is based on some speculation, but I assume that at some point you make a copy either implicitly or explicitly.
All of the three crash causing members are trivially constructible. Since you don't initialise them in the constructor, they are left with an indeterminate value (assuming non static storage).
When you copy such object, the values of the members are read. Behaviour of reading an indeterminate value (of these types) is undefined. When behaviour is undefined, the program may crash.
The issue was that there were two separate sets of Derived.h/Derived.cpp files. One of them was outdated and left lingering around, forever forgotten.
The set I have been working on was included in the C++ project itself, but source file which was including the actual header file was using the old path.
This resulted in discrepancy between h and cpp files, resulting in heap corruption due to different memory signatures of header file included in the project and header file actually included by one of the cpp files in the project.
Quite a lot of debugging and headaches solved by one-line #include path change.

Qt multiple inheritance ambiguous base class

So, my class hierarchy looks something like this:
QObject QGraphicsPolygonItem
\ /
\/
CBubble
/\
/ \
CListBubble CSingleLinkBubble
\ /
\/
CActionBubble
The reason I'm doing multiple inheritance is because I have another bubble that is a CListBubble (LB), but not a CSingleLinkBubble (SB).
The error I receive is "CBubble is an ambiguous base of CActionBubble".
I've tried the virtual tag on one or both of them.
I've tried adding "virtual CBubble" to CActionBubble.
I've tried changing to "public virtual CBubble" in LB and SB, but that causes issues in all bubbles that inherit from them.
I could forego CListBubble entirely and copy/pasta the code, but that goes against all my instincts. I could try to refactor this to use the decorator pattern, but that seems like a lot of unnecessary work for this one case.
Any help or suggestions are much appreciated.
Thanks.
EDIT:
I apologize, should have read the MCVE rules.
Note - I just typed this up now, so hopefully there aren't any syntax issues, but I assume it gets the point across.
clistbubble.h
// header guard
#include "cbubble.h"
class CListBubble : public CBubble
{
public:
CListBubble(const QPointF & pos, QGraphicsItem *parent = 0);
// data members/methods
};
clistbubble.cpp
#include "clistbubble.h"
CListBubble(const QPointF & pos, QGraphicsItem *parent)
: CBubble(pos, parent) // rest of base member initialization
{
// other stuff for this type of bubble
}
// Other methods
The header for CSingleLinkBubble is equivalent in all but members and methods.
cactionbubble.h
// header guard
#include "csinglelinkbubble.h"
#include "clistbubble.h"
class CActionBubble : public virtual CSingleLinkBubble, public virtual CListBubble
{
public:
CActionBubble(const QPointF & pos, QGraphicsItem *parent);
// data members/methods
};
cactionbubble.cpp
#include "cactionbubble.h"
CActionBubble(const QPointF & pos, QGraphicsItem *parent)
: CSingleLinkBubble(pos, parent), CListBubble(pos, parent) // rest of base member initialization
{
// other stuff for this type of bubble
}
I'm concerned that the issue lies in the constructor of CActionBubble where both parent classes are called. However both calls are necessary and would happen anyway if I implemented a default ctor.
The error points me to the place I attempt to new a CActionBubble.
"CBubble is an ambiguous base of CActionBubble"
I also forgot to mention that CBubble inherits from QObject so I can implement signals and slots. I read something awhile back that multiple inheritance with QObject is not possible. Could it be that this is the actual issue, and the error just points one layer below?

Segfault when using std::set of pointers... can anyone explain this?

In my game I created a base class called Entity which I store in a set for processing. All my game objects derive from this class, and I have no problem adding the derived pointer types to the set in my initialization function.
The problem lies in adding new elements from within an Entity's Step() function. Now, before I get too far into it I'll show you some simplified code:
class GameState
{
public:
GameState();
~GameState();
...
set<Entity*> entities;
void Add(Entity* e);
void Remove(Entity* e);
protected:
set<Entity*> added, removed;
};
class Entity
{
public:
Entity();
Entity(GameState* parent);
virtual ~Entity();
virtual void Step(const sf::Input& input);
...
virtual void Destroy();
protected:
GameState* game;
};
The functions Add and Remove in GameState simply add the argument e to the added and removed sets respectively. In the main loop (elsewhere in GameState), I move the elements from added to entities before processing and after processing I remove elements from removed from entities. This ensures that entities is not modified during iteration.
The Add/Remove functions are very simple:
void GameState::Add(Entity* e)
{
added.insert(e);
}
void GameState::Remove(Entity* e)
{
removed.insert(e);
}
Every derived Entity is passed a pointer to GameState in it's constructor that it keeps as game. So theoretically from the Step function I should be able to Add and Remove entities with a simple call like game->Remove(this);, but instead I get a segfault. After a night of googling and coming up with nothing, I was able to work around (part of) the problem by implementing Entity::Destroy() like so:
void Entity::Destroy()
{
game->Remove(this);
}
So my first question is: Why does this work when I'm in the base class but not in the derived class?
Even more puzzling to me is Add(). Why does Add(new Explosion(16,16,this)) work in GameState but game->Add(new Explosion(16,16,game)) doesn't work inside my object?
I ran it through gdb and it tells me:
Program received signal SIGSEGV, Segmentation fault.
At c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:482
The code that throws the error is:
_Link_type
_M_begin()
{ return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } //this line
So to sum it up I have no idea why my pointers break the STL... and I get that grave feeling that I'm missing something very basic and its causing all these headaches. Can anyone give me advice?
Why does Add(new Explosion(16,16,this)) work in GameState but
game->Add(new Explosion(16,16,game)) doesn't work inside my object?
If that is the case then the only possible explanation is that the Entity's game member doesn't actually point to the GameState. Check that it is being set properly on construction and verify before you use it.
This has nothing to do with std::set. The problem is that you are using an std::set that is part of a class that you are accessing via a corrupt pointer.

C++ new() crashing before calling ctor

thank you for looking at my problem.
I have an object that is being dynamically created in my program. The creation is part of a loop and the first iteration works fine.
Upon creation, my object base class adds itself to a map.
Here is some sample code :
public class Base {
Base() {
// Add itself to a map
Data::objects[key] = this;
}
}
public class Derived : public Base {
// This ctor only initialize one int field.
Derived() : Base() {};
}
Kinda simple isn't it ?
In my code, I do Derived * d = new Derived(); and for some silly reason, I get a SIGSEGV.
I tried to debug it, but it doesn't even enters the ctor before crashing!
Here is my call stack so you can help me better:
Address: #0x002c0000
ntdll!RtlReleasePebLock()
Address: #0x0000000c at c:...\stl_deque.h:514
msvrct!malloc()
libstdc++-6!_Znwj()
fu87_ZSt4cerr(this=0xbc1ad8, e="//my object name//") at //my object name//.cpp
... Other are my lines.
Thank you, Micael
{enjoy}
Edit: Adding informations about the map
The map is located in a data class, statically.
// Data.h
class Data {
static map<int, Base*> objects;
}
// Data.cpp
#include "Data.h"
map<int, Base*> Data::objects;
// methods implementations
How can you corrupt the heap, how can I find a corruption has occured?
Has Data::objects been initialized prior to the creation of ANY of the usages of Base?
You are not guaranteed that the class object objects had been initialized whenever you have more than one translation unit (read, .cpp file) in the final link target, unless you've gone to special effort to ensure it.
Most people solve this problem by using a static class through which this initialization is guaranteed to have occurred on first use. Something like:
// untested code, typed in by hand, not compiled through a machine compiler.
class Base {
public: static addObject(Base* that);
Base::Base() { Base::addObject(this); }
};
class Derived: public Base {
Derived::Derived() {}
};
//
// and in the .CPP for Base
namespace /* hidden */ {
int object_number = 0;
map<int,Base*> *objects = NULL;
}
void Base::addObject(Base* that) {
// TODO: do something to avoid multi-thread issues if that is ever a concern
if (!objects) {
objects = new map<int,Base*>();
}
(*objects)[++object_number] = that;
}
You've probably corrupted the heap at some point prior to the allocation, which causes the crash. Try running with valgrind to see where you're going wrong