I have a template class called OrdinalObjectList which is simply a map with a key of int and object pointers. It's purpose is to provide an collection of object pointers that can be accessed by an ordinal key. Here is the class:
template <typename O>
class OrdinalObjectList {
public:
std::map<int, O*> List;
OrdinalObjectList() {};
virtual ~OrdinalObjectList()
{
// Need to delete the objects in the map
typename std::map<int, O*>::iterator i;
for (i = List.begin(); i != List.end(); i++)
{
O* d = i->second;
delete d;
}
};
On destruction of the OrdinalObjectList, the destructor loops through the map and deletes the objects. This has worked fine up until now, however it is currently receiving a EXC_BAD_ACCESS error when deleting the second of two objects in the collection.
On the first pass d is 'FSCE::Customer' * 0x10088e600 which delete's without issue. On the second pass, d is 'FSCE::Customer' * 0x100897e00 which, when delete'd causes the EXC_BAD_ACCESS. I can access the members of the second 'd' in the debugger. i.e. d->lifeid int 2, indicating that the FSCE::Customer object is a valid object and that 'd' is a valid pointer.
What steps should I take next to track down the cause of the EXC_BAD_ACCESS?
I can't tell for sure, but it is it possible your deleting the 1st and (nonexistent) 2nd items, rather than the 0th and 1st items? Make sure you're deleting what you think you're deleting.
EXC_BAD_ACCESS can easily be traced by enabling zombie objects.
For XCode 4.x see How do I set up NSZombieEnabled in Xcode 4?
For other versions of XCode you can find it on the internet.
Edit: Below is incorrect.
Not really an answer, however when I reduced the number of threads to 4, the problem goes away. Previously I had set the number of threads to 8, the boxen is Core i7, which is 4 cores with Hyper Threading.
I can only assume that there is a problem with Hyper Threading, either in the OSX kernel or LLVM. I have optimisations set to O3, at some point I will turn off optimisations and see if that works on 8 threads, however in the meantime, 4 threads is only 10% slower than 8, so I will stick with that so I can progress.
The problem was with a large array within the objects I was deleting. The array was created in the constructor and deleted in the destructor similar to this (data member names have been changed):
Matrix::Matrix(int maxa, int maxb, int maxc)
{
asize = maxa;
bsize = maxb;
csize = maxc;
matrixsize = a * b * c;
matrix = new double [matrixsize];
}
Matrix::~Matrix()
{
delete [] matrix;
}
So far so good, however in setting the values in the matrix I had a bug.
void Matrix::SetValue(int a,int b,int c,double value)
{
int index = (a * asize) + (b * bsize) + c;
matrix[index] = value;
}
The bug in another part of the code that set 'maxc' meant that sometimes index would be greater than matrixsize, which I discovered by adding a check and throw.
void Matrix::SetValue(int a,int b,int c,double value)
{
int index = (a * asize) + (b * bsize) + c;
if (index >= matrixsize) throw;
matrix[index] = value;
}
This would result in access to memory outside that which was allocated in the constructor, and when the delete was called, the EXC_BAD_ACCESS error being raised. The curious thing is why the EXC_BAD_ACCESS was not raised in Matrix::SetValue during execution, but I guess the answer has something to do with there being no bounds checking on array index offsets against the heap manager's memory bounds. If anyone can shed light on that I would be most interested, but for now, this answer is for anyone who finds this answer from a web search.
Related
I'm trying to use pointers (because I need them), but for some reason, I don't understand them. (The explanation is under the code snipped)
void Spiel::SetFigureToField(Figur *figur)
{
*figur->teampos = *figur->*spieler->GiveTeamPos();
figur->teampos = figur->spieler->GiveTeamPos();
figur->pos = figur->teampos;
this->spielfeld[figur->Startpoint].Figuren.push_back(figur);
std::vector<Figur*>* figs = &figur->spieler->SpawnField;
for (int i = 0; i < figs.size(); i++) //find figure in spawnfield and erase it
{
if (*figs[i] == figur)
{
*figs.erase(*figs.begin() + i);
}
}
}
struct Figur
{
Spieler* spieler{};
int Startpoint{}; //startpoint on spielfeld
int teampos{0}; //pos in Array | 0 best - 4 worst | 5 spawnfield
int pos{};
int id{};
void reset(int team, int pos)
{
if (team == 0) this->Startpoint = 0;
else this->Startpoint = 21;
teampos = pos;
}
};
class Spieler
{
public:
Spieler(std::string wuerfelS, int team);
//Stats
int Wins{ 0 };
int AnzahlWuerfen{ 0 };
//for game
int FigursActive{ 0 }; //keepstrack of the figurs on field
Wuerfel wuerfel{};
std::vector<Figur>figuren{};
std::vector<Figur*>SpawnField{};
Figur* ZielFeldArray[4];
int GiveTeamPos();
};
Okay, the first function is my problem point.
Explanation of how it should function: So a Figur (pointer) gets passed in the function and it should place to a gamefield.
What I understand: I want to edit the teampos in the figur. So what i learn is that I should dereference it (so I get the values from the memory address), but if i do *figur->teampos it just gives me an error.
The other one:
std::vector<Figur*>* figs = &figur->spieler->SpawnField;
With this I should get the pointer of the SpawnField vector. What I thought is that i have to dereference it to use the values and methods of vectors. *figs.size() This is what I tried and it gives an error.
It's clear that I don't understand pointers, but every tutorial says: if you have a pointer you have to dereference it to access the values (okay makes sense), but it doesn't function
I'm trying use pointers (because i need them), but for some reason i dont understand them.
How can you be so sure you need them if you don't understand them? I really mean this question, as many programmers, even good one, will be convinced that a solution is the best, but in reality a misunderstanding of the problem is at the core of the issue instead.
What i understand: I want to edit the teampos in the figur. So what i learn is that i should dereference it (so I get the values from the memory address), but if i do *figur->teampos it just gives me an error.
C++ has two dereferencing operators. The unary star *ptr and the arrow ptr->. If you use the arrow figur->teampos then you already deferencence figur here. ptr->member is semantically equivalent to (*ptr).member.
The other one: std::vector<Figur*>* figs = &figur->spieler->SpawnField; with this i should get the pointer of the SpawnField vector. What I thought is that i have to dereference it to use the values and methods of vectors. *figs.size() This is what i tried and it gives an error.
To access the vector's member, you should use the arrow: figs->size() as the star operator cannot access members directly.
Same thing when indexing. doing vec_ptr[1] will do the [] operator on the pointer, but should be on the vector itself. You will need (*vec_ptr)[1].
I'm currently trying to get work done in a threaded member function of my class. Therefore it gets a 2d array as parameter and fills it in the member function. This gets repeated multiple times. Right after spawning the first thread I get an error with either read or write access violation. I tried different approaches to solve it, but can't get it to work. While I found nearly any problem already solved here, in this case I was unsuccessful finding something for quite a while now.
void myClass::process(Vector3D& out_stack, long filterFaktor){
long rowSize = this->input2D.size();
long colSize = this->input2D.at(0).size();
int filterPerRowCount = ceil((double)rowSize / filterFaktor);
int filterPerColCount = ceil((double)colSize / filterFaktor);
std::vector<std::thread> threadPool;
//create new filter
long currentrow = 0;
while (currentrow < rowSize) {
long currentcol = 0;
while (currentcol < colSize) {
Filter* nextFilter = &this->createNextFilter(currentrow, currentcol, filterPerRowCount, filterPerColCount);
out_stack.push_back(Vector2D());
Vector2D* nptr = &out_stack[out_stack.size()-1];
//Here we are calling the thread which leads to the access violation
threadPool.push_back(std::thread(&myClass::nextProcess, this, nextFilter, nptr, rowSize, colSize));
currentcol += filterPerColCount;
}
currentrow += filterPerRowCount;
}
//wait until threads have finished
for (int iThread = 0; iThread < threadPool.size(); iThread++) {
threadPool[iThread].join();
}
}
void myClass::nextProcess(Filter* nextfilter, Vector2D* out_Map, long rowCount, long colCount){
//Loops this part -> creates the rows and pushes them in the out_Map
std::vector<double> nextRowInMap;
//... Calculates sum
nextRowInMap.push_back(sum);
//Push row in vector -> This is where the error occurs
out_Map->push_back(nextRowInMap);
}
typedef std::vector<double> Vector1D;
typedef std::vector<Vector1D> Vector2D;
typedef std::vector<Vector2D> Vector3D;
I think I'm just missing knowledge in using Pointers in C++, cause I'm new to it.
Thanks in advance & best regards
EDIT
Tried it now this way, still doesn't work:
out_stack.push_back(Vector2D());
long index = out_stack.size() - 1;
threadPool.push_back(std::thread(&myClass::nextProcess, this, nextFilter, &out_stack, index, rowSize, colSize));
And in nextProcess:
out_stack->at(index).push_back(nextRowInMap);
EDIT
Solved with mutex. Additionally I needed to pass the filter not on reference.
You error is here:
out_stack.push_back(Vector2D());
Vector2D* nptr = &out_stack[out_stack.size()-1];
There is no guarantee that the object stays at the same address when you modify the vector.
When the vector has to grow it can allocate the internal memory on another address and move the objects in the vector to a new address. So the pointer can get invalid on the next push_back
You should pass the vector and index to the thread and access it each time you need it
out_stack[index].push_back(...)
It may be that after out_stack[index] and before push_back the vector gets modified and you are also operating on invalid memory. So you should protect accessing/modifying the vector with a std::mutex. I am not sure on that last part though if there is some thread safety guarantee there I don't know of.
I create a 2D array of Nodes (Node class is in a separate file) and i'm wondering how to deallocate exactly this (below). I've tried many ways and mem leaks still appear.
board = new Node * [r];
//creats a column for each element in the row
for(int i = 0; i < r; i++) {
board [i] = new Node [c];
}
(r is the rows and c is the cols)
I've done this:
for(int i = 0; i < r; i++) {
delete [] board[i];
}
delete [] board;
But apparently it's not enough
The code you have is correct and sufficient. However, it would be better to use RAII so that you do not need to explicitly call delete at all (perhaps not even new). For example, you could create a std::vector<std::vector<Node>>, or better still, some sort of matrix class (not in the standard library, unfortunately).
Your solution is the correct way to free two dimensional array. However you may still get a memory leak if Node uses dynamic memory and it's destructor is not properly defined.
As others have said, you're correctly pairing up all your new[]s and delete[]s: assuming no errors occur, the memory allocated by this code will be correctly deallocated.
The only issue is that errors may occur, and in particular exceptions may be thrown:
new[] can throw an exception if it fails to allocate memory (doesn't normally happen on desktop OSes, but you should still write code as if it does.)
Node's constructor may throw. Even if you've designed the constructor not to throw you generally shouldn't take advantage of that knowledge. Just write code as if throws.
In fact, you should just generally write code as if pretty much anything can throw. For more detailed info on writing exception safe code, and on what the exceptions to this rule are you can read the info at http://exceptionsafecode.com
The best way to make this code exception safe is to use RAII. For example use a vector instead of new[]/delete[].
Using an array of pointers and a separate allocation for each row makes sense for 'ragged' arrays, where each row can be a different length. In your case you have rectangular array, so you can use a single allocation for the whole thing.
std::vector<Node> board(rows*columns);
board[row_index*columns + column_index] // replaces board[row_index][column_index]
You can hide the implementation by putting this in a class:
class Board {
std::vector<Node> board_data;
public:
const int rows;
const int columns;
Board(int rows_, int columns_)
: board_data(rows_*columns_)
, rows(rows_)
, columns(columns_)
{}
struct board_index { int row, column; };
Node &operator[](board_index i) {
assert(0 <= i.row && i.row < rows);
assert(0 <= i.column && i.column < columns);
return board_data[i.row * columns + i.column];
}
};
Board board(r, c);
with the above implementation you replace board[i][j] with board[{i, j}].
board[{i, j}] = ... // assign to a place on the board
board[{i, j}].foo(); // call a Node method
std::cout << board[{i, j}]; // print a Node
// etc.
Like i said in the title i cant get the destructor to work. The reason being is that in this program i am required to use a int* array with negative indices: I keep getting this error at random times while running also: Microsoft C++ exception: std::bad_alloc at memory location 0x009DF130.
heres the code that i believe involves the error:
private: int* run;
IntArray::IntArray(int a, int b)
{
int c = b-a;
run = new int [c] + a; //This is how i give it a negative indicie
h = b;
l = a;
}
IntArray::~IntArray()
{
delete[]run;
}
string IntArray::setName(string sp)
{
s = sp;
return s;
}
void runSim() {
IntArray b(-4, 6);
for (int i = b.low(); i <= b.high(); i++)
// low is the lowes bound high is the highest
b[i] = i * 10;
b.setName("b"); //this is where it breaks and gives me that error
wait();
}
The only right way to do this is to define a custom operator[] on your class. The code you have has numerous errors:
You access both low and high, that's high-low+1 elements. But you only allocate high-low.
If p=new int[high-low+1], then run=p+low; and run[low] means *(p + low + low). This is the proximate cause of your crash -- you wrote way outside the array, trashing internal metadata, which made dynamic allocation fail for the next user, your string's assignment operator.
You should have subtracted low when computing run, so that run[low] would give p[0], the first allocated element. But this might calculate a pointer outside the array (when low is positive), which is undefined behavior.
You pass a pointer to delete[] that didn't come from array new. You need to pass p, not run, to delete[].
You have no attempt at exception safety. Management of dynamic memory in C++ is an advanced topic, and the evidence shows that you are not ready to do it yet. So use an existing smart pointer to manage your memory.
Here's a better version:
#include <memory>
template<typename T>
class ArbBoundArray
{
int low;
std::unique_ptr<T[]> base;
public:
ArbBoundArray(int l, int h) : low(l), base(new T[h-l+1]) {}
T& operator[](int o) { return base[o-low]; }
const T& operator[](int o) const { return base[o-low]; }
};
That's it. Less code, works for any type not just int, and exception-safe.
You can add your special needs like a name or whatever on top of that basic concept.
Your have a simple errors:
Do not pass a value to delete [] you didn't get from new [] (or already passed once).
You need to undo your pointer-arithmetic to get the right pointer.
Also, be aware that if you create a pointer which points outside the array using pointer-arithmetic, you have Undefined Behavior.
If that's not your actual code, beware of trying to allocate less than 1 element.
Since you add a (aka l) to run when you new it, you must subtract when you delete it:
delete[] (run - l);
Not trying to be mean, but this is pretty bad code.
First of all, if b - a returns a number less than 0 you will probably get an std::bad_alloc and if a > c you will be stepping into undefined behaviour [scary] territory and will probably get a segfault if you try to use the pointer.
Seeing as though you try to delete[] the pointer that points to new int[c] + a you almost certainly will get a segfault.
You need to do run -= a before trying to delete[] it, the implementation will either store information about any new or malloc in the space before the pointer that you get given so that when you delete or free the memory it just has to run behind the pointer and get any information it needs or store the info in a hidden array somewhere that is indexed by the numerical representation of the pointer. But probably the first. Either way, you're screwed doing what you're doing.
I have a vector of pointers to a class. I need to call their destructors and free their memory. Since they are vector of pointers vector.clear() does not do the job.So I went on to do it manually like so :
void Population::clearPool(std::vector<Chromosome*> a,int size)
{
Chromosome* c;
for(int j = 0 ;j < size-1;j++)
{
c = a.back();
a.pop_back();
delete c;
printf(" %d \n\r",j);
c = NULL;
}
}
The printf in there is since I have a talking destructor to see in which Chromosome the segmentation fault happens. When clearPool() is called and say we got a size of 100, it can give a segmentation fault in any Chromosome between 0 and 100.
I have no idea why this might be happening nor do I have a way to actually find what's wrong since while debugging with breakpoints all I see is that it happens in there at random chromosomes.
I am using codeblocks IDE and the gdb debugger. The stack trace when the segmentation fault happens has 4 memory addresses and a function wsncpy().
void Population::clearPool( std::vector <Chromosome*> & a )
{
for ( int i = 0; i < a.size(); i++ ) {
delete a[i];
}
a.clear();
}
Notice that the vector is passed by reference. In your code, a copy of the vector is used, which means that it is unchanged in the calling program. Because you delete the pointers in the copy, the pointers in the original are now all invalid - I suspect you are using those invalid pointers in some way not shown in the code you posted.
As a couple of template solutions have been posted that use C++ library algorithms, you might also want to consider a template solution that does not:
template <class C> void FreeClear( C & cntr ) {
for ( typename C::iterator it = cntr.begin();
it != cntr.end(); ++it ) {
delete * it;
}
cntr.clear();
}
Using this you can free any container of dynamically allocated objects:
vector <Chromosome *> vc;
list <Chromosome *> lc;
// populate & use
FreeClear( lc );
FreeClear( vc );
Slight modified version compared to (#1800 INFORMATION).
struct DeleteFromVector
{
template <class T>
void operator() ( T* ptr) const
{
delete ptr;
}
};
std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());
I don't know why you are crashing, but I guess that one possibility is that the size of the vector is not the same as the size you are passing in. Also I notice you are iterating from 0 to size-2, do you not mean to go all the way to the end?
One way to delete all of the items in the array using idiomatic C++ is something like this:
template<class T>
class deleter
{
public:
void operator()(const T* it) const
{
delete it;
}
};
std::for_each(a.begin(), a.end(), deleter<Chromosome>());
Boost lambda already has a functor for deleting sequences of pointers, by the way:
std::for_each(a.begin(), a.end(), boost::lambda::delete_ptr());
Are you sure that each pointer in the vector points to a different object?
(i.e. that two pointers don't both point to the same object, which you're trying to delete twice.
Are you sure that you don't delete some of the pointers before calling this method?
(i.e. are you sure that each pointer in the list points to a valid object?)
The most likely reason is calling delete twice for the same address. This can happen if you added one object more than once to the vector. To detect this insert some statement that will output the address of the object you will then delete.
printf( "will delete %d\n", (int)c );
delete c;
I found the problem.
It was in the most well hidden (by none other than stupid old me) place it could be.
As some might have guessed this is a genetic algorithms program. It is for a tutorial I am making. I was choosing the crossover points for the chromosomes randomly from a roulette wheel function which I made. Well ... inside there, there was a -1 which should not be there. That destroyed literally everything, and eventually lead to a segmentation fault.
Thank you all for your help, I saw some really good practises in this post which I intend to follow
I recommend to use smart pointer (ie:auto_ptr) instead of raw pointer and just use vector::clear method that will call the destructor for each element
void Population::clearPool(std::vector<Chromosome*>& a)
{
for(size_t i = 0; i < a.size(); i++) {
delete a[i];
}
a.clear();
}
It seems, that some pointers in your code do not reference correct Chromosome objects. This may happen, if you try to delete some objects twice as a result of code:
Population p;
vector<Chromosome*> chromosomes;
p.clearPool(chromosomes,chromosomes.size()); // You pass by value, so chromosomes is not changed
p.clearPool(chromosomes,chromosomes.size()); // Delete already deleted objects second time
You may find useful ptr_vector from Boost Pointer Container Library in order to avoid similar errors