I cant get my destructor to work in my code - c++

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.

Related

Pointer dereference causes error when using arrow operator

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].

How could I create my own string-type vector with new string instead of allocator?

I wrote a very simple code just to see if the allocator would work as allocating memory for string. And it works. However, I would like to know if I could achieve the same effect with new keyword. If I could, which method would be a better practice ? My code sample is as following:
#include<iostream>
#include<string>
#include<memory>
class MyVector{
private:
int size;
int capacity;
std::allocator<std::string> str;
std::string*a;
void allocate(){
capacity = (size-1)*2;
std::string*temp = str.allocate(capacity);
for(int i=0; i<this->getSize();++i){
temp[i] = a[i];
}
str.deallocate(a, 1);
a = temp;
}
public:
MyVector():size(0), capacity(1), a(str.allocate(1)){};
int getSize(){return size;};
int getCapacity(){return capacity;};
void pushBack(std::string input){
++size;
if(this->getSize()>this->getCapacity()){
this->allocate();
}
a[this->getSize()-1]=input;
}
std::string at(int index){
for(int i=0; i<this->getSize();++i){
if(i==index){
return a[i];
}
}
return 0;
}
};
int main(){
MyVector v;
v.pushBack("Sam");
std::cout<<v.at(0)<<std::endl;
return 0;
}
If I understand your question correctly, you're trying to allocate a bunch of strings dynamically, and would like to know whether you can use operator new() to perform the allocation, and in case you can, which method is the best.
There are a few problems with your implementation I have to point out before being able to answer your question. So let's walk through it!
std::string* a doesn't get deallocated when MyVector is destroyed
This is the most obvious one. There is no destructor, and you are manually managing a raw pointer, which therefore must be deallocated! Right now, when MyVector goes out of scope, the memory pointed to by a is going to become unreachable, and there will be no garbage collector to clean it up.
Therefore we'd have to add a method like this:
~MyVector() { str.deallocate(a, capacity); }
What if this->allocate() can't allocate, and throws std::bad_alloc when you're doing a push_back?
size has already been incremented, and the capacity has been updated but the string you were trying to push hasn't been copied, and the buffer hasn't grown, which leaves your container in an invalid state. You would probably end up accessing memory outside of the bounds of your buffer, which is undefined behavior (this could work, crash, or even get your male cat pregnant)
Alright, this can be fixed easily by putting the assignments after the actual allocation has happened. No big deal. Right?
What if when trying to copy the strings from the old buffer to the new, one of them can't allocate its own internal buffer?
Well it's going to throw std::bad_alloc in the middle of the loop. And your temp buffer is never going to be deallocated. Ouch.
This is getting serious. We could put a catch clause in there, but this is starting to be a lot of code just for maintaining the pointer in a good state.
Isn't temp[i] = a[i]; calling the assignment operator on uninitialized memory, which would be another undefined behavior?
I'm not 100% certain on this one, but my C++ instinct tells me this is pretty risky.
So, how do I get out of this long list of issues?
Use new instead? Maybe new[] because this is an array of strings?
Well, this would be cleaner, especially if you're going to use the default std::allocator anyway.
But wait, there's better!
Looking at the C++ Core Guidelines, we can see under P.8 that we shouldn't leak any resources, it is advised to use RAII, and to look for "naked new". Basically, what that means is that you should avoid using new in normal code to allocate resources dynamically. Instead, the guidelines encourage you to use unique_ptr and to use make_unique() to construct objects owned by unique_ptrs
As a reference, here is unique_ptr's page on cppreference. You can also read a bit more about it here, or watch one of the designers of the language explain the concepts I touched on much better than I could on YouTube
Following these guidelines, your code could become much more modern-conforming. It would look like this:
#include<string>
#include<memory>
class MyVector{
private:
int size;
int capacity;
std::unique_ptr<std::string[]> a;
void allocate(){
size_t new_capacity = size*2;
auto temp = std::make_unique<std::string[]>(new_capacity);
std::copy(a.get(), a.get()+size, temp.get());
capacity = new_capacity; // We have finished all the operations that could throw!
std::swap(a, temp); // Because this can't throw
}
public:
MyVector():size(0), capacity(1) {}
// Since unique_ptr<>'s destructor is called automatically
// we don't need to do it explicitely!
int getSize(){return size;};
int getCapacity(){return capacity;};
void pushBack(std::string input){
if(this->getSize() == this->getCapacity()){ // We have to change the comparison
this->allocate();
}
a[this->getSize()] = input; // This could throw too!
++size;
}
std::string at(int index){
if(index >= size)
throw std::out_of_range("Trying to access an element past the end in MyVector!");
return a.get()[index];
}
};
One final note
This container is still pretty inefficient (a growth factor of 2 is not the theoretical best, although I don't know that much more about it), it has no notion of move semantics, it can't be copied, it can't be specialized for other types (although that wouldn't be too difficult), it doesn't have handy iterators to use with algorithms or a range-based-for loop, and so on.
It is, however a very good learning exercise, and I applaud you for trying to improve on it by posting your result on StackOverflow :)
Making a production-ready container is actually a lot of work, and requires quite deep hardware knowledge to get right, so as a conclusion I would advise you to stick to std::vector for when you actually need to use a vector somewhere ;)

EXC_BAD_ACCESS when trying to delete valid pointer (xcode c++)

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.

C++ std::vector of pointers deletion and segmentation faults

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

Memory Allocation in Recursive C++ Calls

I'm having problems allocating and deallocating my memory in a recursive C++ program. So without using an automatic memory management solution, I wonder if anyone can help me resolve the memory leak I am experiencing.
The following code essentially explains the problem (although it's a contrived example, please correct any mistakes or simplifications I've made).
A number class to hold the value of a number:
class Number {
public:
Number() { value = 1; };
Number& operator + (const Number& n1) const {
Number result = value + n1.value;
return result;
};
int value;
};
Two functions to perform the recursion:
Number& recurse(const Number& v1) {
Number* result = new Number();
Number one = Number();
*result = *result + recurse(one);
return *result;
}
int main(...) {
Number answer = Number();
answer = recurse(result);
}
As you can see the memory allocated in the recurse function is leaked, but I'm not sure where I can free up this memory from based on the nature of the recursion?
The problem is here:
Number& operator + (const Number& n1) const {
Number result = value + n1.value;
return result;
};
You're returning a local variable (result) by reference, and that's a big NO-NO. Local variables are allocated on the stack, and when the function exits, the variables are gone. Returning a reference to a local variable is returning a pointer into the stack that's now being used for something else, and that's going to cause lots of badness.
What you should instead do is return by value (just change the return type from Number& to Number). Make sure you have an appropriate copy constructor, or that the compiler's automatically generated copy constructor suits your needs. This means when operator+ returns, it makes a copy (which can often by optimized away), and since there's no pointers or references involved, you can't get a corrupted return value.
To fix your memory leak, you can use smart pointers such as boost::shared_ptr. Alternatively, ditch pointers and dynamic memory altogether, and just return your results by value from recurse().
I don't see why you're allocating the memory on the heap to begin with:
Number& recurse(const Number& v1) {
Number result;
Number one;
// I assume there is a step here to determine if the recursion should stop
result += recurse(one);
return result;
}
By allocating only on the stack you're guaranteed that the variables will be cleaned up when the function returns.
Otherwise I think you'd have to use some sort of smart pointer.
So I see three other problems in the code other than returning the address of a local variable that Adam Rosenfield pointed out.
First, your resursive function will never end. At some point in recurse(), you must check for a value that causes it to not call recurse() again and just return. That is a fundamental part of recursion. The argument passed, v1, is also not being used.
Second, the operator+() does not actually work. There is not a way to assign an int to a Number() object.
Third, in main you pass something called result which is never declared.
Forgetting those errors, I assume that you want to allocate all the objects on the heap to avoid a stack overflow, where this function will recurse many times or the actual object used is much larger than Number. In that case by allocating the return variable on the heap inside recurse() you are forcing the caller to delete the returned object. So after the calls to recurse() in recurse() and main() you would have to delete the returned value. The convention for indicating that to the caller is to return a pointer instead of a reference. So recurse() and main() would look something like this:
Number* recurse(const Number& v1) {
Number* result = new Number();
Number one;
if(v1.value >= 2) {
Number temp;
temp.value = v1.value - 1;
Number* partialResult = recurse( temp ); //capture the object to delete
*result = *partialResult + one;
delete partialResult; //delete the object
}
return result;
}
int main() {
Number result;
result.value = 15;
Number *answer;
answer = recurse(result);
delete answer;
}
Note: Whatever recurse actually calculates is nonsensical. I don't know what the intentions are but it is just something that works.
Is there some reason you are dynamically allocating the memory?
Number recurse(const Number& v1) {
Number result;
Number one;
retun result + recurse(one);
}
Also I notice you are not using the value v1
But the big mistake is that the recursion has NO escape clause.
This is in effect an infinite recursion that will basically run out of memory.
Smart pointers are your friend. Do a quick read-up on auto_ptr at the very least.
Also, read Adam Rosenfield's comment on your other problem (returning a reference to a value that doesn't exist anymore).