I am using a double pointer but when I try to delete it it causes Heap Corruption: CRT detected that the application wrote to memory after end of heap. It "crashes" inside the destructor of the object:
Map::~Map()
{
for(int i = 0; i < mTilesLength; i++)
delete mTiles[i];
delete[] mTiles;
}
mTiles is declared something like this:
Tile **mTiles = NULL;
mTiles = new Tile *[mTilesLength];
for(int i = 0; i < mTilesLength; i++)
mTiles[i] = new Tile(...);
If notable mTiles is a object of "Tile" which inherits from a object "Sprite" all 3 destructors are set as virtual (map, tile, sprite), not sure if that makes any difference but seemed to work until now.
The code you posted does not seem to have any problems in it. I created a simple, self contained, compiling (and correct) example from it:
struct Tile {int x; Tile():x(7) {}};
struct Map {
Tile **mTiles;
int mTilesLength;
Map(int TilesLength_);
~Map();
};
Map::~Map()
{
for(int i = 0; i < mTilesLength; i++) {
delete mTiles[i];
}
delete[] mTiles;
}
Map::Map(int TilesLength_):
mTiles(),
mTilesLength(TilesLength_)
{
mTiles = new Tile *[mTilesLength];
for(int i = 0; i < mTilesLength; i++) {
mTiles[i] = new Tile();
}
}
int main() {
Map* m = new Map(1000);
delete m;
}
I compiled and ran it <- link, and nothing bad was noticed.
Your problem lies in code you have not shared with us. In order to find the code that is causing the problem and ask the right question, go here: http://sscce.org/
Then take your code and start trimming parts off it until the code is simple, yet still demonstrates your heap corruption. Keep copies of each version as you trim away irrelevant code so you don't skip over the part where the problem occurs (this is one of the many reasons you want a version control system even on your personal projects).
Related
I have memory leaks inside my code but I couldn't figure out a solution to free the memory allocated inside the function where the object is created and pushed into a vector of an object.
The main function is the following:
void foo(vector<vector<BCC>> &features){
vector<MinutiaPair*> matchingMtiae;
for (int i = 0; i < features.size(); i++){
Match(features[0], features[i], matchingMtiae);
ms += s;
// Free memory
for (int j = 0; j < matchingMtiae.size(); j++)
delete (matchingMtiae[j]);
matchingMtiae.clear();
}
Each step of the loop a comparison is executed between values and a "new" vector matchingMtiae is returned with new objects. Then, for the next iteration, I want to completely free this vector and deallocate its content from memory. The Match function where objects are created and pushed into a vector matchingMtiae is presented below:
void Match(vector<BCC> &qt, vector<BCC> &tt, vector<MinutiaPair*> &reducedMatchingPairs) {
vector<MinutiaPair*> localMatching;
for (int i = 0; i < qt.size(); i++)
for (int j = 0; j < tt.size(); j++)
{
double currSim = qt[i].Match(tt[j], true);
if (currSim > 0)
{
qt[i].minutia.Flag = false;
tt[j].minutia.Flag = false;
MinutiaPair *pair = new MinutiaPair(qt[i].minutia, tt[j].minutia, currSim);
localMatching.push_back(pair);
}
sort(localMatching.begin(), localMatching.end(), MtiaPairComparer::ComparePointers);
for (int k = 0; k < localMatching.size(); k++)
{
if (!localMatching[k]->QueryMtia->Flag || !localMatching[k]->TemplateMtia->Flag)
{
reducedMatchingPairs.push_back(localMatching[k]);
localMatching[k]->QueryMtia->Flag = true;
localMatching[k]->TemplateMtia->Flag = true;
}
else
{
delete (localMatching[k]);
}
}
}
Debugging my code I realized that after the delete and clear of the vector matchingMtiae, the objects created were still allocated in memory and I can not understand the reason why this is happening since the pointer is not being lost but keeping it inside the vector.
I would like to deallocate the created objects from memory and completely clean the vector from pointers. Both are my aims.
Thanks in advance.
You can "submit" a non-binding request to the C++ library std::vector to release its allocated memory by calling shrink_to_fit after clear or resize.
Note this is nonbinding which practically means every sane implementation actually releases memory but you cannot portably rely on this assumption strictly speaking.
I would also strongly suggest replacing the raw pointers in your vector with std::unique_ptr (or even just the objects themselves, if there is no concern of inheritance/slicing). It will ease the visual load of your function and prevent memory leaks in the future.
Well, I have a class which is supposed to be a container for quadratic polynomials (which is a template and I'm using floats there, but that shouldn't matter much). I made it using a dynamic array, and I was supposed to overload + and - operators... Not a problem, eh? Well, it seemed all nice and dandy until I actually run it.
listf listf::operator+(listf rhs)
{
listf newlist;
for(int i = 0; i < elementcount; ++i)
newlist.add(array[i]);
for(int j = 0; j < rhs.elementcount; ++j)
newlist.add(rhs.array[j]);
std::cout<<newlist;
return newlist;
}
Nothing much. Should do its job correctly, right? That cout is just to check if it works. But it does not.
Should do something like this, right?
With one list consisting of:
X^2+5x+52.4
2X^2+7x-12
and the second one having just X^2+2X+1, it should make a list and display:
X^2+5x+52.4
2X^2+7x-12
X^2+2X+1
Buuuut no, it comes to this:
-1.5584e+038X^2-1.5584e+038x-1.5584e+038
-1.5584e+038X^2-1.5584e+038x-1.5584e+038
-1.5584e+038X^2-1.5584e+038x-1.5584e+038
I've been battling with it for quite some time and have not found why it would do that.
Code for adding new polynomials is still quite simple:
void listf::add(polynomial<float> plnm)
{
if(array == NULL)
{
++elementcount;
array = new polynomial<float>[elementcount];
array[0] = plnm;
}
else
{
array = resize(array, elementcount+1, elementcount);
array[elementcount++] = plnm;
}
}
And resize is a private function in this class:
polynomial<float>* listf::resize(polynomial<float>* arr, int newSize, int oldSize)
{
polynomial<float>* newArr = new polynomial<float>[newSize];
for(int i = 0; i < oldSize; ++i)
{
newArr[i] = arr[i];
}
delete[] arr;
return newArr;
}
If we're making a smaller array (for deleting objects), I just put oldSize equal to newSize (I know it's a bad practice and confusing for others, but I was just testing things :( )
I'm out of ideas. Adding new elements to an object seems working, but when I want to add two objects it breaks, prints elements that are not correct and then crashes with CodeLite reporting something like "ntdll!LdrVerifyImageMatchesChecksumEx" in Call Stack. Even better, when I tested it right now, it displayed correct values, but still crashed at return.
Forget the home-made dynamic array and use vector. Whenever you go into the realm of classes and memory management, it isn't as trivial as coding up a few new[] and delete[] calls. It can stop you dead in your tracks in the development of your program.
#include <vector>
//...
typedef std::vector<polynomial<float> > PolynomialFloatArray;
//...
class listf
{
PolynomialFloatArray array;
//...
void add(const polynomial<float>& plnm);
//...
PolynomialFloatArray& resize(PolynomialFloatArray& arr, int newSize)
};
//...
void listf::add(const polynomial<float>& plnm)
{
array.push_back(plnm);
}
PolynomialFloatArray& listf::resize(PolynomialFloatArray& arr, int newSize)
{
arr.resize(newSize);
return arr;
}
There in a nutshell is all of that code you wrote, reduced down to 2 or 3 lines.
Like the comments on the question point out, you would probably be better off using std::vector for this, as it has push_back() to add stuff to the end, and automatically resizes itself to do so, though you can force it to resize with resize().
Hi I'm coding a C++ program containing a loop consuming too much unnecessary memory, so much that the computer freezes before reaching the end...
Here is how this loop looks like:
float t = 0.20;
while(t<0.35){
CustomClass a(t);
a.runCalculations();
a.writeResultsInFile("results_" + t);
t += 0.001;
}
If relevant, the program is a physics simulation from which I want results for several values of an external parameter called t for temperature. It seems that the memory excess is due to not "freeing" the space taken by the instance of my class from one execution of the loop to the following, which I thought would be automatic if created without using pointers or the new instruction. I tried doing it with a destructor for the class but it didn't help. Could it be because the main memory use of my class is a 2d array defined with a new instruction in there?
Precision, it seems that the code above is not the problem (thanks for the ones pointing this out) so here is how I initiate my array (by the largest object in my CustomClass) in its constructor:
tab = new int*[h];
for(int i=0; i<h; i++) {
tab[i] = new int[v];
for(int j=0; j<v; j++) {
tab[i][j] = bitd(gen)*2-1; //initializing randomly the lattice
}
}
bitd(gen) is a random number generator outputing 1 or 0.
And also, another method of my CustomClass object doubles the size of the array in the following way:
int ** temp = new int*[h];
for(int i=0; i<h; i++) {
temp[i] = new int[v];
for(int j=0; j<v; j++) {
temp[i][j] = tab[i/2][j/2];
}
}
delete[] tab;
tab = temp;
Could there be that I should free the pointer temp?
You're leaking memory.
Could there be that I should free te pointer temp?
No. After you allocate the memory for the new array of double size and copy the contents, you should free the memory that tab is pointing to. Right now, you're only deleting the array of pointers with delete [] tab; but the memory that each of those pointers points to is lost. Run a loop and delete each one. Only then do tab = temp.
Better still, use standard containers that handle memory management for you so you can forget messing with raw pointers and focus on your real work instead.
So this is a reduced version of my main / Initializer function. When I call it and it has to add any items to the players inventor, I get a Debug Assertation Failed error.
It seems to me like I am mixing up the scope somewhat?
Am I declaring something new inside the scope of the function, and then not being able to access it again out in main?
I tried a few things inside the function, like using Getters/Setters instead of assigning is completely, like p_player = p but I don't think that actually deals with the problem at all, and I'm kind of confused.
int main()
{
Array<Item> items(3);
string itemsfilename = "itemsfile.txt";
Initializer::InitializeItems(items, itemsfilename);
Login login;
Player p1;
string filename = login.LoginToGame();
Initializer::InitializePlayer(p1, rooms, items, 3, filename);
}
void Initializer::InitializePlayer(Player& p_player, HashTable<string, Room>& p_rooms, Array<Item>& p_items, int p_numItems, std::string& p_filename)
{
ifstream playerfile(p_filename);
int inventorycount = 0;
//all the stuff needed to make a player
std::string name;
int health;
int confidence;
int humor;
int speed;
std::string room;
Room* currentRoom;
Inventory inventory(100);
//reading in values from file
for(int i = 0; i < inventorycount; i++)
{
playerfile.getline(value, 256);
std::string item(value);
for(int j = 0; j < p_numItems; j++)
{
if(p_items[j].GetName() == item)
{
inventory.AddItem(&(p_items[j])); //This line taken out, removes the error.
}
}
}
Player p(name, health, confidence, humor, speed, currentRoom, inventory);
p_player = p;
}
AddItem() takes a pointer to an item, and then appends it to it's DLinkedList.
Edit:
The error I get is
Debug Assertation Failed!
Program: zzz
File f:\dd/vctools/crt_bld/self_x86/crt/src/dbgdel.cpp
Line: 52
Expression: _Block_TYPE_IS_VALID(pHead->nBlockUse)
AddItem() Code:
bool AddItem(Item* p_item)
{
if(p_item->GetWeight() + m_weight <= m_maxWeight)
{
m_inventory.Append(p_item);
m_weight += p_item->GetWeight();
}
else
{
return false;
}
return true;
}
Ok, so we still don't have the code that actually causes the problem, but I'm pretty certain I know what's going on, and to avoid getting into a "20 questions of add more code" - there's two possible scenarios:
Items is an array of objects, and you store pointers to them in your m_inventory container. When destroying this container, the objects are destroyed by calling delete on the items - which doesn't work since the content is not allocated from the heap.
When you copy the inventory the m_inventory container is not appropriately copied, and the contents fall apart because the pointers to the storage is failing.
If this doesn't help, then please try to reduce your code to something that only shows this problem, without using files that we don't know the content of and can be posted as a complete program in the question with all the code necessary [remove any other code that isn't needed], so we can see EVERYTHING. Currently, we're only seeing a few bits of the code, and the problem is almost certainly DIRECTLY in the code you've shown us.
I want to create a SDL-based Hanoi Tower Game, but before I proceed to writing "engine", I wanted to test my Hanoi in a console. Surprisingly, it turned out to be quite buggy.
CTower tower[3];
tower[0] = CTower(3);
tower[1] = CTower(3);
tower[2] = CTower(3);
init(&tower[0]); //prepare first tower
tower[0].Print();
This piece of code should create 3 arrays (of size 3) and fill 'em with 0 (zeros). Then, in init(), I prepare the first tower (fill it with vaild discs). However simple may it seem, my application halts on printing and doesn't fill the remaining arrays (with 0). What's strange, function init() works just fine.
I would appreciate any help.
Here's some code to check:
class CTower {
uint16 *floors, floorsNum;
void Init();
public:
(...) //definitions, probably of zero importance
};
void CTower::Init() {
//private member, filling with zeros
for (uint16 i = 0; i < floorsNum; i++)
floors[i] = 0;
}
CTower::CTower() {
//default initialiazer
floors = NULL;
floorsNum = 0;
}
CTower::CTower(uint16 nfloors) {
floors = new uint16[nfloors];
floorsNum = nfloors;
this->Init();
}
CTower::~CTower() {
delete[] floors;
floorsNum = 0;
}
void CTower::Print() {
if (floorsNum == 0) printf("EMPTY TOWER!");
else
for (uint16 i = 0; i < floorsNum; i++)
printf("%d\n", floors[i]);
}
void init(CTower *tower) {
//a friend method of CTower
for (uint16 i = 0; i < tower->floorsNum; i++)
tower->floors[i] = i+1;
}
My application source: https://rapidshare.com/files/2229751163/hanoi-tower.7z
Problem is with your initialisation and allocation of your class. It seems you have forgotten that Resource Acquisition is Initialisation.
You are facing a free corruption : you call delete[] on a not allocated attribute.
You have this constructor :
CTower::CTower() {
//default initialiazer
floors = NULL;
floorsNum = 0;
}
Which does NOT allocates memory but which is destroyed with :
CTower::~CTower() {
delete[] floors;
floorsNum = 0;
}
A simple way to fix your program is to allocate directly with the working constructor :
int main(void) {
CTower tower[3] = { CTower(3), CTower(3), CTower(3) };
init(&tower[0]);
tower[0].Print();
printf("\n");
tower[1].Print();
return 0;
}
But it would be far better to also fix your Class, either in Destructor or in Constructor part.
Unless you have been specifically asked not to use a std::vector then I would consider changing your code to use one as it makes life a lot simpler.
With regards to your specific code example. You are going to have problems due to the lack of a copy constructor and assignment operator as the defaults generated by the compiler are not going to be suitable for your class.
I would also consider getting rid of the friend function void init(CTower *tower) as this really isn't good practice.
I would provide a code example but this question is tagged as "Homework" so I will let you do the research yourself.