Exc_bad_access with pointers - c++

I have been working in a project using matrices and graphs. The problem is when I compile it, the next line pops up:
EXC_BAD_ACCESS (code=2, address=0x7ffff5f3ffff8)
It appears in the next method; which is a constructor of my class:
GrafoMatriz::GrafoMatriz(){
maxVerts = 1;
GrafoMatriz(maxVerts);
}
typedef int * pint;
class GrafoMatriz {
...
int maxVerts;
int numVerts;
Vertice * verts; // there's another class Vertice
int ** matAd;
GrafoMatriz();
GrafoMatriz(int mx);
...
}
GrafoMatriz::GrafoMatriz (int mx){
maxVerts = mx;
verts = new Vertice[mx];
matAd = new pint[mx];
numVerts = 0;
for (int i = 0; i < mx; i++)
matAd[i] = new int[mx];
}
I have been reading about possible problems and it could be something wrong about pointers:
The pointer could have never been initialized.
The pointer could have been accidentally written over because you overstepped the bounds of an array.
The pointer could be part of an object that was casted incorrectly, and then written to.
Any of the above could have corrupted a different pointer that now points at or near this pointer, and using that one corrupts this one (and so on).
I guess it's something about my pointer pint, but I am new to C++. So, I haven't been able to fix it. By the way0, I'm using Xcode 6.4 on an Intel Macbook Pro.

As mentioned by #kuroineko in the comments, you cannot call a constructor from another constructor in C++. If you use C++11 (or a later standard) then you can use delegating constructors. Otherwise you might want to define an initialization function, for example, like this:
void GrafoMatriz::Initialize(int mx){
maxVerts = mx;
verts = new Vertice[mx];
matAd = new pint[mx];
numVerts = 0;
for (int i = 0; i < mx; i++)
matAd[i] = new int[mx];
}
Then you can call this initialization function from your different constructors:
GrafoMatriz::GrafoMatriz(){
Initialize(1);
}
GrafoMatriz::GrafoMatriz (int mx){
Initialize(mx);
}
As far as I can tell, the rest of the shown code should compile. I don't know if the code related to your variable matAd is correct, but at least it doesn't crash for me.

Related

Inserting new element on dynamic array of pointers to objects

I have a class representing an array, holding pointers to my other class objects.
#include "Edge.h"
class Array
{
private:
Edge** _headPtr;
int arraySize;
public:
Array(int);
void pushBack(Edge*);
// other functions...
};
Array::Array(int arraySize)
{
this->arraySize = arraySize;
this->_headPtr = new Edge*[arraySize];
}
Program always returns memory allocation errors after calling
// inserts an element on the end of the array
void Array::pushBack(Edge* element)
{
if (arraySize == 0) {
_headPtr = new Edge*[1];
_headPtr[0] = element;
arraySize++;
}
else {
Edge** _tempPtr = new Edge*[arraySize + 1]; // crashing here
memcpy(_tempPtr, _headPtr, arraySize * sizeof(Edge*));
//for (int i = 0; i < arraySize; i++) delete _headPtr[i];
delete[] _headPtr;
_tempPtr[arraySize] = element;
_headPtr = _tempPtr;
arraySize++;
}
}
I have commented out the for (int i = 0; i < arraySize; i++) delete _headPtr[i];
part because it was causing _free_dbg(block, _UNKNOWN_BLOCK); error.
From what I've found in other questions here I guess there must be a flaw in my understanding of dynamic array of pointers to class objects, but after spending much time trying to fix this I've run out of ideas.
The general idea of my program is to perform time efficiency measurements for some graph algorithms, this being part of Prim's algorithm implementation.
Call stack leading to this situation looks like this:
BinaryHeap queue = BinaryHeap();
queue.addNewElement(new Edge(v, v2, edgeWeight));
which looks like this
void BinaryHeap::addNewElement(Edge* element)
{
heapElements->pushBack(element);
heapFix_UP(heapElements->getSize()-1);
}
And finally pushBack method.
heapElements is Array* heapElements inside the BinaryHeap class, initialized with
heapElements = new Array(); in BinaryHeap constructor.
Edge is a very simple class holding only three integer values.
Please do not suggest using std::vector, the whole idea is not to use STL.
OK, I have found the solution. All of the code above works good, the bug was in a completely different place in my code.
What was so wrong that it was causing the whole program to crash many lines later?
This:
int** graphMatrix;
graphMatrix = new int*[vertex];
for (i = 0; i < edges; i++) graphMatrix[i] = new int[edges];
So simple, yet so harmful.
It is a part of my incidence matrix implementation. Now the reason for all crashes is pretty obvious - trying to write/read unallocated memory and causing heap corruptions.

passing an dynamic array as copy to recursive function c++

I am writing code for a backtracking approach to a Traveling Salesman type of problem. So at each point i will recurse for rest of the un-visited points.
I could not use any library/functions other than cout, cin, new and delete (so no vector). So for the problem i want to keep a track of what all points i have visited till now. I am using a dynamic boolean array for this. So i want to pass the dynamic array to a function as value to keep track of this.
This is what i have tried till now.
I tried to wrap the array in a struct, but the memory dealocation (delete) is giving error (Segmentation fault)
typedef struct Barray{
bool* a;
int size;
Barray(int size) { a = new bool[size]; this->size = size; }
Barray(const Barray& in) {
if(a) delete[] a; // error
a = new bool[in.size];
this->size = in.size;
for (int i = 0; i < in.size; i++)
a[i] = in.a[i];
}
~Barray() { delete[] a; } // error
}barray;
This is my recursive function call
void find_mindist(barray visited, int dist_now, int cur_p) {
if (base condition)
{return ;}
for (int i = 0; i < n; i++) {
if (visited.a[i]) continue;
barray tdist = visited;
tdist.a[i] = true;
int ndist = dist_now + dist(points[cur_p], points[i]);
find_mindist(tdist, ndist, i);
}
return ;
}
So my questions are -
how can i pass a dynamic array to a function as value?
Why is the delete above giving error?
First of all, the recommended approach for a local visited information is not the endless copying of the whole visited collection, but a mark->recurse->unmark approach. So whatever you do, please keep a single boolean array for the visited information and update its content to your needs.
The other problems occur because you try to delete an uninitialized pointer in the copy constructor. Also, the assignment operator should be overloaded as well to avoid unpleasent surprises. But non of this really matters if you don't copy your visited information anymore.
The problem this is a copy constructor. As such, on entry, a is uninitialized (so contains garbage), so the delete is invalid.
Barray(const Barray& in) {
if(a) delete[] a; // error
a = new bool[in.size];
this->size = in.size;
for (int i = 0; i < in.size; i++)
a[i] = in.a[i];
}
Just remove the delete line. Also, prefer to initialize members, rather
than assign them, so:
Barray(const Barray& in)
: a(new bool[in.size])
, size(in.size) {
for (int i = 0; i < in.size; i++)
a[i] = in.a[i];
}
Also, remember the Rule of Three. You need an copy assignment operator. The simplest is:
Barry& operator=(const Barray& in) = delete;
which just forces a compilation error if you try to use it! Better is:
Barry& operator=(const Barray in) { // **NOTE** pass by value!
std::swap(this.a, in.a);
std::swap(this.size, in.size);
}
This version provides the strong exception guarantee. You aren't allowed to use std::swap, so you'll either have to write your own, or write it out by hand (you choose).
Finally, if you ever find yourself returning a Barray, you should write a move constructor:
Barray(Barray &&in)
: a(in.a)
, size(in.size) {
in.a = nullptr;
}
This can save a lot of copying!

Pointer of class to void*

i am working on a rpg games with class
i created a struct call Character with ActionList* which store the instance.
GeneralPlayer is a class where there have still a bunch of other players classes inherited it.
This is my header file:
class Battle
{
public:
struct Character
{
char type;//monster or player?
bool alive;
void*instance;//pointer to instance
};
Battle(GeneralPlayer*,AbstractMonster*,int,int,int);
Battle(GeneralPlayer*, AbstractMonster*, int, int);
private:
Character *ActionList;
};
i was trying to convert GeneralPlayer* to void*. However seems like the code doesnt work as i thought. P and M are array of pointers of those player classes.
Battle::Battle(GeneralPlayer*P, AbstractMonster*M, int a, int b, int c)
{
a = numP;
b = numM;
c = turn_limit;
ActionList = new Character[numP + numM];
P = new GeneralPlayer[numP];
for (int i = 0; i < numP; i++)
{
ActionList[i] = static_cast<void*>(P[i]);
ActionList[i].type = 'p';
}
for (int i = numP; i < numP+numM; i++)
{
ActionList[i] = static_cast<void*>(M[i]);
ActionList[i].type = 'm';
}
}
it keeps showing the error C2440. I wish can solve my problem with anyone helps thank you.
You are trying to convert object into pointer, use the & operator to get the pointer in question.
ActionList[i] = (void*)&P[i];
ActionList[i] = (void*)&M[i];
One of the problems here is that the Character structure is not a parent of either GenericPlayer or AbstractMonster. It seems that the Character::instance member should be pointing to the player or monster, which means your code should be something like
ActionList[i].type = 'p';
ActionList[i].alive = true;
ActionList[i].instance = &P[i];
This is assuming that the list of players is already initialized by the caller of the Battle constructor, then you should not allocate a new array of players, so the P = new GenericPlayer[numP]; statement should be removed.
It should be noted that having something like you do, a "generic pointer" (what void * is) and then a member saying what type it's really pointing to is considered bad design. Instead you would have a common base-class for both monsters and players, and use a pointer to that. Then with the correct use of polymorphism and virtual member functions you don't need the type field. And then it's easy to refactor the code to use some other means of telling if a player or monster is alive or not, and then you don't need the Battle::Character class at all, and could use an array of pointers to the common base class instead, thus simplifying the code a bit, which is very good for maintainability.
There are a few other problems with the code as you show it, things that will cause problems later at runtime.
One problem is that in the loop iterating over the monsters, you initialize o to numP and loop up to numP + numM, but if the array M doesn't contain numP + numM elements you will go out of bounds.
Instead I suggest you do e.g.
for (int i = 0; i < numM; i++)
{
ActionList[i + numP].type = 'm';
ActionList[i + numP].alive = true;
ActionList[i + numP].instance = &M[i];
}

Why can't I reassign a variable that was formerly allocated on the stack in C++ (copy assignment operator of 'Frame' is implicitly deleted)?

I have the following setup:
struct Frame {
Frame(vector<Region> regions_)
: regions(regions_){}
const vector<Region> regions;
};
Now, at a different part in my code I want to create a vector<Frame> and created the following for loop:
vector<Frame> shot;
Frame currentFrame = generateRandomFrame();
for (int i = 0; i < length; i++) {
shot.push_back(currentFrame);
currentFrame = generateNextFrame(currentFrame); // this line gives the error
}
where generateNextFramehas the following signature:
Frame FrameGenerator::generateNextFrame(Frame previousFrame)
Now, this code won't compile and give me the following error:
copy assignment operator of 'Frame' is implicitly
deleted because field 'regions' has no copy assignment
operator const vector<Region> regions;
Now, I don't fully understand this error message. I strongly assume that it's related to the fact that currentFrame is allocated on the stack and not on the heap, and thus I can't just reassign the variable. Being a novice to C++ however, I am not familiar with how to handle these kinds of situations. Should I use pointers here instead and try to allocate currentFrame on the heap?
To be clear, my goal is to generate a series of frames (that depend on some previous frame). Can anyone point me into the right direction here?
Update:
Thanks a lot for all the hints in the comments, I now understand that the issue comes from the fact that I declare regions as const. I rewrote the code to use pointers instead of heap variables, it now looks like this:
vector<Frame> shot;
Frame currentFrame = generateRandomFrame();
Frame *currentFramePtr = &currentFrame; // the first frame in the shot is random
for (int i = 0; i < length; i++) {
shot.push_back(*currentFramePtr);
Frame tmpFrame = generateNextFrame(*currentFramePtr);
currentFramePtr = &tmpFrame;
}
This code does compile now, however it still doesn't do what I want. According to my understanding it should now work, because I am storing the currentFrame in a pointer, so I can easily override it with new objects that I create. But it seems that there still is a bug, the frame generation doesn't work as expected (that is any new frame is generated with 0 regions while the number of regions should be identical to the previous frame). Can anyone see what's wrong with this updated version of my code?
Your struct declares a const member, which forces compiler to implicitly delete default copy assignment operator due to the fact that const member doesn't have copy assignment operator.
The code below replaces the bits you omitted from the sample and shows how to generate a bunch of Frame *s instead of Frames. Basically, it's a workaround for your compilation issue, but it may not suit your specific need if your code REQUIRES stack usage or you'd have to refactor too much.
#include <iostream>
#include <vector>
struct Region{};
struct Frame {
Frame(std::vector<Region> regions_)
: regions(regions_){}
const std::vector<Region> regions;
};
int main(int argc, const char * argv[]) {
std::vector<Frame *> shot;
Frame * currentFrame = new Frame((std::vector<Region>()));
for (int i = 0; i < 10; i++) {
shot.push_back(currentFrame);
currentFrame = new Frame(std::vector<Region>());
}
return 0;
}
Also please note:
how to use const_cast? - const_cast won't work for you and will cause UB. Just in case ;)
If you absolutely insist on keeping regions const, and having "assignment", you can destroy the existing Frame and create a new one in place.
std::vector<Frame> shot;
Frame currentFrame = generateRandomFrame();
for (int i = 0; i < length; i++) {
shot.push_back(currentFrame);
currentFrame.~Frame();
new (&currentFrame) Frame(generateNextFrame(shot.back()));
}
However an even easier way would be to not reassign anything
std::vector<Frame> shot;
shot.push_back(generateRandomFrame());
for (int i = 1; i < length; i++) {
shot.push_back(generateNextFrame(shot.back()));
}

Segfault with vector of pointers to vectors

I have narrowed down the problem to this line:
indg = nets[i]->adjlist[i].size(); // indg is in a method of the Ensemble class
Where the above variables are
vector<DDNetwork*> nets; // this vector is in the Ensemble class
int indg;
class DDNetwork
{
friend class Ensemble;
...
public:
vector< vector<int> > adjlist; // the adjacency list of the network
...
};
I don't understand why indg = nets[i]->adjlist[i].size(); would cause a segfault, is there something I am missing? Also if you need more information I can add it.
EDIT: I just realized what was wrong, I am using the same index for adjlist that I am for nets, the line
indg = nets[i]->adjlist[i].size();
should be:
indg = nets[i]->adjlist[j].size();
EDIT: After stepping through the debugger, I noticed that in the constructor of Ensemble, nets.size() = 10 (expected), but when the method Ensemble::alloc_dev_memory is called, nets.size() = 803384 (unexpected), so I think that JaredPar's second suggestion might explain the problem. Here is the code that adds DDNetwork* instances into the nets variable:
Ensemble::Ensemble(int N, float K, int S, bool seedrand, int ltype, int numNets)
{
this->N = N;
this->K = K;
this->S = S;
this->ltype = ltype;
this->numNets = numNets;
if(seedrand)
srand(time(0));
nets.resize(numNets); // make a vector of pointers to DDNetwork
for(int i=0; i < numNets; ++i)
nets[i] = new DDNetwork(N,K,S,seedrand,ltype);
// pre-compute the S^k for k=0,1,...,Kmax
Spow[0]=1; // S^0 = 1
int k=1;
while(k <= Kmax*2) {
Spow[k] = S*Spow[k-1]; // S^k = S*(S^(k-1))
++k;
}
}
This constructor is called when I instantiate the ensemble variable in my main function:
// instantiate ensemble of networks
Ensemble ens(N, K, S, seed_rand, multiedge, numNets);
// run_the ensemble one time step
ens.run_gpu();
And after that, Ensemble::run_gpu calls Ensemble::alloc_dev_memory, then when nets[i]->adjlist[j].size() is called, that's when I receive the segmentation fault.
How would the nets reference get uninitialized?
The problem is likely one of the following
The DDNetwork* reference in nets[i] is uninitialized causing a segfault when you access the members.
The size of nets and each instance of adjlist is not kept in sync causing one of the offsets to be invalid
Could you post the code which adds DDNetwork* instances into the nets variable?
There are two possibilities. Either there isn't a new DDNetwork at index nets[i] or adjlist[i] hasn't been created.
To have a square vector of vectors you need to resize them properly:
adjlist.resize( MAX );
for (int i = 0; i < MAX; ++i)
adjlist[i].resize( MAX );
...only then can you index them. Alternatively you can push_back proper values.
Note also that you use the same index for the nets array, and the adjlist array, unsure whether that was intended.
I found the source of the segfault by accident, I was doing some crude debugging because GDB didn't have information about my main.cpp file, and in order to print out nets.size(), I had to temporarily make vector<DDNetwork*> nets public, after doing that, I realized that the program didn't segfault anymore. I thought it might have to do with the private/public distinction, but when I moved the line
public:
vector<DDNetwork*> nets;
private:
to
public:
private:
vector<DDNetwork*> nets;
line, the program still didn't segfault, so I tried moving the line vector<DDNetwork*> nets; back to where it used to be, all the way below all of the other method and member declarations, just before the closing brace };, and the program began to segfault as before. What is it about the location of the line vector<DDNetwork*> nets; that was causing the segfault?