Debug assertion failed - Vector iterator not dereferencable - c++

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.

Related

Why does pass by reference cause this to crash (C++)?

I'm experiencing some weird behavior and I'm not really sure where to turn.
Basically, I have a set of classes and one of them should be constructed with instances of the other two. I'm using pass by reference to assign the resources but the second assignment is crashing on my machine. I don't understand why the second assignment crashes but the first works fine. To make this a little more confusing, I tried recreating the problem in an online cpp compiler, but it seems to run fine in that environment.
I obscured the class names and removed a few methods that didn't seem relevant to this problem. Does anyone have any ideas?
#include <iostream>
using namespace std;
class Driver{};
class ITransmission{};
class ManualTransmission : public ITransmission {};
class Car
{
public:
Car(ITransmission &trans, Driver &driver);
private:
ITransmission *m_trans;
Driver *m_driver;
};
Car::Car(ITransmission &trans, Driver &driver)
{
*m_trans = trans;
*m_driver = driver; // <-- **** Crashes here!?!? ****
}
int main()
{
ITransmission *trans = new ManualTransmission();
Driver *driver = new Driver();
Car car(*trans, *driver);
return 0;
}
*m_trans and *m_drivers are only pointers to their respective types. They are not the object themselves. In your copy constructor you are calling
*m_trans = trans
which crashes because m_trans doesn't point to anything and you are dereferencing it.
What you want instead is,
m_trans = &trans
m_driver = &driver
This sets the pointer to point at the address of the object you've passed in, whereas before you were trying to assign to the pointed-to object.

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.

self-document a returned data-structure of a function that uses one-frame allocator

How to self-document a function that use a custom allocator - to remind that its user must not cache the returned result.
I have a library and a user class, they use in-house polymorphic allocator.
Library : uses one-frame-allocator to generate return result of Library:fLib .
The returned result will be invalid at the end of time-step.
User : want to cache the return result of Library:fLib to use in later frame.
It is a bad design ; hence it needs some warning.
Here is the snippet. (full demo).
class Library{
public:
OneFrameAllocator allo_;
public: Report fLib(){ //<-- may need some semantic documentation
Report report;
report.setAllocator(&allo_);
return report;
}
};
Library lib;
class User{
Report tmpCache;
public: void fUser(){
Report arr=lib.fLib(); //<-- still OK (should not warn)
tmpCache=arr; //<-- wrong usage, but hard to detect
}
};
int main(){
User user;
user.fUser();
lib.allo_.clearOneFrame();
//HERE: user.tmpCache become dangling pointer internally (danger)
return 0;
}
Question
How to warn coder of User not to cache return result of Library::fLib() semantically
(i.e. more than just comment /**/)?
I am considering to use smart pointer, but I don't think it can help because memory become invalidated from custom allocator, not from deleting a unique_ptr.
In real life, Library can also be a custom Array (that acts similar as std::vector).
In such case, the danger less obvious - "User try to copy Array" doesn't seem to be dangerous.
Sorry if the question is too newbie, I am very new to custom allocators.
Edit:
After looking into the rule of three. (thank paddy)
I believe the core of my problem can be depicted as :-
(pseudo code)
class Lib{
OneFrameAllocator allo;
public: std::unique_ptr<int> make_unique(){
return allo.make_unique<int>();
//^ memory will be invalidated when call "allo.clearOneFrame()"
}
public: void update(){
allo.clearOneFrame();
}
};
Library lib;
class User{
std::unique_ptr<int> cache=nullptr;
public: void fUser(){
//do something about "cache" <--- crash expected at 2nd frame
std::unique_ptr<int> temp=lib.make_unique(); //<-- still OK
cache=std::move(temp); //<-- danger
}
};
int main(){
User user;
//--- 1st frame ----
user.fUser();
lib.update();
//--- 2nd frame ----
user.fUser(); //<--- crash expected
lib.update();
}
I believe the problem is :
The class that has ownership (User) is not the class that controls memory allocation (Library).
It is not a good design, so I want to find a way to warn the coder of User that something is wrong by using C++ syntax/semantic-clue.

Class vector c++ issue

I'm having some trouble with vector class. For some reason, yet to be found :P, I can't insert any objects to my vector. I've tried vector, map, deque, etc, but they all have the same weird result.
The object that I want stored is a class with 2 std::string in it. Here's some code to explain my point:
vector<DnsAddress> * dnss = new vector<DnsAddress>;
for(int i = 0; i < ns.size(); i++){
DnsAddress dn;
dn.SetRecord1(record1);
dn.SetRecord2(record2);
cout<<dn.GetRecord1()<<" : "<<dn.GetRecord2()<<endl; //this works, so it is inserting info to the object
dnss->push_back(dn);//this is where it begins to fail...
cout<<dnss->at(i).GetRecord1()<<" : "<<dnss->at(i).GetRecord2()<<endl;//doesn't work
DnsAddress a = dnss->at(0);//this way doesn't work either...
cout<<"dns: "<<a.GetRecord1()<<endl;
}
I'm sure there must be a rookie mistake.. I hate when those happen.. They consume me some time to find out.
Can someone give a hand with this?
I appreciate it :)
To claify:
There are no errors... It works without problem... but the info in the vector gets counted(.size() function tells me the number of inserted objects) but when you try to access it, nothing is shown... But no error is raised
This is class DnsAdress:
class DnsAddress {
public:
DnsAddress();
DnsAddress(const DnsAddress& orig);
virtual ~DnsAddress();
void SetRecord2(string record2);
string GetRecord2() const;
void SetRecord1(string record1);
string GetRecord1() const;
private:
string record1;
string record2;
};
This is just a guess since you didn't show your class DnsAddress or tell us what the error was.
My guess:
Your class doesn't have a copy constructor (compile time error) or
The copy constructor isn't making a correct copy (run time misbehavior).
I'll bet your DnsAddress class needs a copy constructor. This effectively gets invoked when you call push_back on a vector of non-pointer elements.
Edit: Looks like you do have a copy constructor. Actually if you just deleted the copy constructor, the default one would work fine. If you still want to implement it manually, you'll need to assign record1 and record2 to to orig.record1 and orig.record2 in your copy constructor implementation.

Vector Troubles in C++

I am currently working on a project that deals with a vector of objects of a People class. The program compiles and runs just fine, but when I use the debugger it dies when trying to do anything with the PersonWrangler object. I currently have 3 different classes, one for the person, a personwrangler which handles all of the people collectively, and a game class that handles the game input and output.
Edit: My basic question is to understand why it is dying when it calls outputPeople. Also I would like to understand why my program works exactly as it should unless I use the debugger. The outputPeople function works the way I intended that way.
Edit 2: The callstack has 3 bad calls which are:
std::vector >::begin(this=0xbaadf00d)
std::vector >::size(this=0xbaadf00d)
PersonWrangler::outputPeople(this=0xbaadf00d)
Relevant code:
class Game
{
public:
Game();
void gameLoop();
void menu();
void setStatus(bool inputStatus);
bool getStatus();
PersonWrangler* hal;
private:
bool status;
};
which calls outputPeople where it promptly dies from a baadf00d error.
void Game::menu()
{
hal->outputPeople();
}
where hal is an object of PersonWrangler type
class PersonWrangler
{
public:
PersonWrangler(int inputStartingNum);
void outputPeople();
vector<Person*> peopleVector;
vector<Person*>::iterator personIterator;
int totalPeople;
};
and the outputPeople function is defined as
void PersonWrangler::outputPeople()
{
int totalConnections = 0;
cout << " Total People:" << peopleVector.size() << endl;
for (unsigned int i = 0;i < peopleVector.size();i++)
{
sort(peopleVector[i]->connectionsVector.begin(),peopleVector[i]->connectionsVector.end());
peopleVector[i]->connectionsVector.erase( unique (peopleVector[i]->connectionsVector.begin(),peopleVector[i]->connectionsVector.end()),peopleVector[i]->connectionsVector.end());
peopleVector[i]->outputPerson();
totalConnections+=peopleVector[i]->connectionsVector.size();
}
cout << "Total connections:" << totalConnections/2 << endl;
}
Where hal is initialized
Game::Game()
{
PersonWrangler* hal = new PersonWrangler(inputStartingNum);
}
0xBAADFOOD is a magic number to alert you to the fact that you're dealing with uninitialized memory. From the stack trace, we see that this in PersonWrangler::outputPeople is invalid. Thus hal doesn't point to a valid PersonWrangler (that is, assuming frame 4 is a call to Game::menu). To resolve this sort of thing yourself, step through the code, starting at Game::Game(), examining Game::hal as you go, to see what might be going wrong.
In Game::Game, hal is a local variable that shadows Game::hal. When Game::Game exits, this hal goes out of scope and leaks memory, while Game::hal remains uninitialized. What you want is:
Game::Game()
{
hal = new PersonWrangler(inputStartingNum);
}
Debuggers fill uninitialized memory with magic numbers to make it easier to spot errors. In a production build, memory isn't filled with anything in particular; the content of uninitialized memory is undefined, and might hold valid values. This is why a production build might not fail when a debug build will.
Did you initialize hal to point to an actual PersonWrangler object?
Creating a pointer does not point it at an actual object unless you do it explicitly. You probably want to either pass a PersonWrangler to your Game at construction time, or have the Game constructor create a PersonWrangler using new. If you choose the latter, make sure to delete your PersonWrangler somewhere, probably in the Game deconstructor.