Defining a pointer randomly crashes the program - c++

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.

Related

Learning C++ and having a problem correclty separating class interface from implementation

I'm learning C++ using Xcode and have written several small programs including a hangman game but I'm having trouble every time I try to separate a class into definition and implementation. I made a simple case that shows my problem. Short version is it seems that I need to specify a type in the implementation file even though it is already defined in the header file. I get "C++ requires a type specifier for all declarations" on lines 12 and 13 in my example. But if I change line 12, for example, to
int xmlelem::atrb_count = 0;
it gets the error "non-static data member defined out-of-line". In other cases I have got an error saying that I was trying to redefine something. I think I'm missing a fundamental concept somewhere. I did not see this particular issue in the handful of similar questions I looked at.
xmlelem.hpp
// xmlelem.hpp
// learn header
//
//
#ifndef xmlelem_hpp
#define xmlelem_hpp
#include <stdio.h>
#include <string>
#endif /* xmlelem_hpp */
class xmlelem {
private:
int atrb_count;
std::string tag_name;
public:
xmlelem(std::string tag);
void add_atrib();
std::string output();
};
xmlelem.cpp
// xmlelem.cpp
// learn header
//.
//
#include "xmlelem.hpp"
#include "string"
#include <iostream>
// line 11
xmlelem::atrb_count = 0;
xmlelem::tag_name = "";
xmlelem::xmlelem(std::string tag){
tag_name = tag;
}
void xmlelem::add_atrib(){
atrb_count++;
}
std::string xmlelem::output(){
std::string build = "<";
build = build + tag_name + " " + std::to_string(atrb_count);
build = build + ">";
return build;
}
and main.cpp
// main.cpp
// learn header
//
//
#include <iostream>
#include "xmlelem.hpp"
using namespace std;
int main(){
xmlelem clip("test)");
std::cout << clip.output() << " test \n";
}
Let's take a look at the (second) error message.
non-static data member defined out-of-line
There are two parts to the error: "non-static data member" and "defined out-of-line". These are incompatible, so one of them must be changed. Furthermore, only one of them should be changed, or else you may run into a different problem. Decide which of the two parts is correct for your situation.
Keep "defined out-of-line"
When the line
int xmlelem::atrb_count = 0;
is encountered at namespace scope (that is, in neither a function nor a class/struct/union definition), it is an out-of-line definition. This definition tells the compiler to reserve, right at that spot, enough space for an int. Then whenever any xmlelem object accesses the atrb_count member, it will access this particular space. So there is one int shared by all objects.
However, this behavior corresponds to a static member. To make the declaration agree with the implementation, the keyword static needs to be added.
class xmlelem {
private:
static int atrb_count;
/* rest of the class definition */
};
Keep "non-static"
A non-static data member is stored inside each object of the class. Each object can do what it wants with its copy of the data without impacting other objects. So telling the compiler to reserve space outside the objects is contradictory. Simply removing the out-of-line definition is enough to get rid of the error message, but presumably you wanted that initialization to occur somewhere, right?
The initialization of non-static data members can be done either in-line or in a constructor. An example of moving the initialization in-line is the following.
class xmlelem {
private:
int atrb_count = 0;
/* rest of the class definition */
};
This is sometimes reasonable, but the stated goal was to separate the interface from the implementation. Therefore, it might be undesirable for the initial value of 0 to appear in the header file, as it does in the above. The alternative is to move the initial value to the constructor (to each constructor, if you had more than one).
xmlelem::xmlelem(std::string tag) :
atrb_count(0),
tag_name(tag)
{
}
(I've also taken the liberty of moving the initialization of tag_name into the initialization list.)
Remember, if you have more than one constructor, this needs to be done in each constructor that actually utilizes the default value (for an exception, think "copy constructor"). Repeated code is a drawback; it is up to you to decide if the gains are worth the cost.
Remember that you are declaring a class. A class is an abstract concept. When you do this xlemem::atrb_count = 0;, you are having a concrete value on an abstract concept. Doesn't make sense, right? You don't think of a particular color when you think of the general concept of dog. Any initiliazations should be done inside the constructor, because only in the constructor is that we create a concrete object.
Therefore, you should eliminate lines 11 and 12 where you initialize these 2 attributes and your constructor code should be changed to:
xmlelem::xmlelem(std::string tag){
tag_name = tag;
atrb_count = 0;
}
Note that it isn't necessary to initialize a string to "".

Why this performance deterioration?

I need to reduce the memory used by my native Windows C++ application, without compromising its performances.
My main data structure is composed by several thousands of instances, dynamically allocated, of the following Line class:
struct Properties
{
// sizeof(Properties) == 28
};
// Version 1
class Line
{
virtual void parse(xml_node* node, const Data& data)
{
parse_internal(node, data);
create();
}
virtual void parse_internal(xml_node*, const Data&);
void create();
Properties p;
};
But since I notice that I could get rid of the class member p, because I only need it within the parse method, I changed the Line implementation:
// Version 2
class Line
{
virtual void parse(xml_node* node, const Data& data)
{
Properties p;
parse_internal(node, data, &p);
create(&p);
}
virtual void parse_internal(xml_node*, const Data&, Properties*);
void create(Properties*);
};
This reduced the memory allocated of several megabytes, but it increased the elapsed time by more than 50 milliseconds.
I wonder how is this possible considering that the application has been compiled for release version with speed optimization fully on. Is it due to the argument passing? Is it due to the stack allocation of my struct Properties?
Update:
The method Line::parse is called just once for each instance. The data structure is composed by a std::vector of Lines. Multiple threads manage a different subset of this vector.
You write that parse_internal is recursive. That means it gets 3 arguments in the changed variant, instead of 2 in the original - and is called recursively a few times.
You also have to access members using pointer syntax instead of element de-referencing (and possibly verify that the Properties pointer is non-null). To eliminate the pointer issues you can use a reference argument to parse_internal.
Is there a reason to have parse_internal as a virtual member function, or could you change it to be static (in the modified variant)?

How to initialize a static member object?

I didn't know that I didn't know this :) . and a similar question here didn't help much.
So here i am asking. Please Consider the following class:
//in Agent.h
class Agent : public ns3::Object{
private:
//...
static BaseWifi m_wifi;
//...
};
is this :
//Agent.cpp
BaseWifi temp;
BaseWifi Agent::m_wifi = temp;
very much different from this:
//Agent.cpp
BaseWifi Agent::m_wifi = BaseWifi();
The second approach doesn't work for me.
why and how?
I don't want to trouble you with more codes coz I faced this problem deep in my program. The program generate seg faults as things(members) inside BaseWifi's constructor are not initialized correctly. when those uninitialized internal members are used, seg faults occur.
Thank you in advance for your kind comments and answers.
p.s.:
In fact I found this issue when I hadn't yet initialized this static member and I was deleting an extra line :
BaseWifi temp;
in my main(), which added more to my confusion!!!(this one could be dependent on what I put in BaseWifi's constructor, so dont mind it for now)
Update-1:
For those who would like to see the BaseWifi:
class BaseWifi {
ns3::WifiHelper m_wifiHelper; // a wifi helper apply to setup vehicles Wifi
ns3::NqosWifiMacHelper m_wifiMacHelper; // a wifi mac helper apply to setup vehicles Wifi
ns3::YansWifiPhyHelper m_wifiPhyHelper; // a wifi phy helper apply to setup vehicles Wifi
std::string m_phyMode;
double m_rss; // -dBm
bool m_init_done;
public:
BaseWifi();
virtual void init();
ns3::NetDeviceContainer Install(ns3::NodeContainer &c);
virtual ~BaseWifi();
};
BaseWifi::BaseWifi() {
m_init_done = false;
m_rss = -80;
m_phyMode ="DsssRate1Mbps";
// TODO Auto-generated constructor stub
init();
}
void BaseWifi::init() {
NS_LOG_UNCOND("inside BaseWifi::init()");
m_wifiHelper.SetStandard (ns3::WIFI_PHY_STANDARD_80211b);
m_wifiPhyHelper = ns3::YansWifiPhyHelper::Default ();
// This is one parameter that matters when using FixedRssLossModel
// set it to zero; otherwise, gain will be added
m_wifiPhyHelper.Set ("RxGain", ns3::DoubleValue (0) );
// ns-3 supports RadioTap and Prism tracing extensions for 802.11b
m_wifiPhyHelper.SetPcapDataLinkType (ns3::YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
ns3::YansWifiChannelHelper wifiChannel;
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
// The below FixedRssLossModel will cause the rss to be fixed regardless
// of the distance between the two stations, and the transmit power
wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",ns3::DoubleValue (m_rss));
m_wifiPhyHelper.SetChannel (wifiChannel.Create ());
// Add a non-QoS upper mac, and disable rate control
m_wifiMacHelper = ns3::NqosWifiMacHelper::Default ();
m_wifiHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode",ns3::StringValue (m_phyMode),
"ControlMode",ns3::StringValue (m_phyMode));
// Set it to adhoc mode
m_wifiMacHelper.SetType ("ns3::AdhocWifiMac");
m_init_done = true;
}
//Install the class's embedded settings on the nodes in this node container.
ns3::NetDeviceContainer BaseWifi::Install(ns3::NodeContainer &nc) {
return m_wifiHelper.Install(m_wifiPhyHelper, m_wifiMacHelper, nc);
}
I have run into these kind of issues before. Apparently the initialization of static member objects very much depends on where the implementation is done in your code and (probably) on how the whole thing is compiled. The solution that I found (somewhere) to the problem was to wrap the whole thing into a static member function like this:
//in Agent.h
class Agent : public ns3::Object{
private:
//...
static BaseWifi& m_wifi();
//...
};
and:
//in Agent.cpp
BaseWifi& Agent::m_wifi() {
static BaseWifi TheObject=BaseWifi();
return TheObject;
}
This way the object is initialized properly the first time the static member function is called.
The difference here is the first approach is using copy constructor to initialize the object while the second is using the default constructor.

Debug assertion failed - Vector iterator not dereferencable

I have got this Runtime Error when running this code:
void AlienShipManager::Update(float timeDelta,
BulletManager* bulletManager,
ParticleManager* particleManager,
GameStringSystem* stringBatch)
{
unsigned int i = 0;
while (i < m_alienShipList.size())
{
AlienResult result = m_alienShipList[i].Update(timeDelta, bulletManager);
switch (result)
{
case AlienResult::Dead:
break;
default:
break;
}
++i
}
}
in line
AlienResult result = m_alienShipList[i].Update(timeDelta, bulletManager);
There is how I add AlienShip to vector class:
m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture));
error also appers if I chance that to:
AlienShip* newAlien = new AlienShip(position, speed, m_screeSize, m_alienShipTexture);
m_alienShipList.push_back(*newAlien);
delete newAlien;
but does not appear if I change that to:
AlienShip* newAlien = new AlienShip(position, speed, m_screeSize, m_alienShipTexture);
m_alienShipList.push_back(*newAlien);
which hence lead to huge memory leaks.
This is how looks my AlienShip class:
#pragma once
#include "Body.h"
#include "BulletManager.h"
#include "ParticleManager.h"
enum AliensShipState
{
flying,
dying,
dead,
escaped
};
enum AlienResult
{
No,
Hit,
Dying,
Dead,
Escaped
};
class AlienShip : public Body
{
public:
AlienShip(void);
AlienShip(float2& position, float2& speed, float2* screenSize, ID3D11Texture2D* alienTexture);
~AlienShip(void);
AlienResult Update(float timeDelta, BulletManager* bulletManager);
void Draw(BasicSprites::SpriteBatch^ spriteBatch);
protected:
float m_baseY;
AliensShipState m_state;
float2* m_screenSize;
};
AlienShip class is inherited from Body class, which has Sprite class inside it, which has another vector inside it.
But since Sprite class is working perfectly elsewhere, I don't think it is source of error.
I wonder why this happens, because I can't find the relationship between deleting temporary object and corrupting vector iterator, If it corrupted at all.
Also program compiles and runs in Release, but with some data corruption.
I am using Visual Studio 2012 Beta for Windows 8.
Please write if you need more source code.
Unfortunately it is very hard to post all code, as this is complex program.
Given that it doesn't work when you add the item to the vector by value but it does when you leak a pointer, I have 95% confidence that your copy constructor for AlienShip does a shallow copy, causing your problems.
EDIT: Note that m_alienShipList.push_back(AlienShip(position, speed, m_screeSize, m_alienShipTexture)); causes a copy of your class and if the copy constructor doesn't work right it will cause problems later.
In fact if the AlienShip definition you've pasted is correct there is in fact only the default copy constructor which likely does the wrong thing (further reinforced by the fact that you have your own destructor).
Either implement a copy constructor that does a deep copy, or more preferably rewrite your class to use RAII to manage the memory for you so that the default copy is correct.

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