Segfault with vector of pointers to vectors - c++

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?

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.

Exc_bad_access with pointers

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.

Unhlandled exception due to bad pointer usage

it's my first question here so I apologize for eventual formal mistakes you may found in my post.
I'm coding a simple class for "Undirected Connected Weighted Graphs", which must use Adjacency Lists based on vectors.
The issue is that when I run the program from Eclipse, MS Windows says it "stops working" and after debugging I get an "Unhandled exception at 0x00AE251A .... Access violation writing location..." message.
Looking around I found that this issue may be caused by a missing pointer destruction or pointer initialization (?). I switched from the standard pointer to the shared_ptr to troubleshoot this issue but the error is the same...
Can anybody enlighten me on this? I lost almost a whole day trying to find the cause without success.
class UndirectedGraph
{
private:
int V;
std::vector<std::shared_ptr<std::pair<int,int>>>* adj;
public:
UndirectedGraph(int V)
{
this->V = V;
this->adj = new std::vector<std::shared_ptr<std::pair<int,int>>>;
}
void addEdge(int v, int w, int weight)
{
auto sp = std::make_shared<std::pair<int,int>>(std::make_pair(v,weight));
adj[v].push_back(sp);
}
int main()
{
UndirectedGraph G1(7);//Ok
G1.addEdge(0,1,9);//Ok
G1.addEdge(1,2,5);//Ok
G1.addEdge(2,0,8);//EXCEPTION RAISED HERE (if line is commented all run fine)
return 0;
}
I noticed a couple of errors in the code:
If what you need are adjacency lists, then this->adj should be a vector of vectors. Currently, its just a 1-D vector of <int,int> pairs. Instead it should be:
std::vector<std::vector<std::shared_ptr<std::pair<int,int>>>>* adj;
In the constructor, this->adj should be initialized as follows:
this->adj = new std::vector<std::vector<std::shared_ptr<std::pair<int,int>>>>(V);
Now, in the addEdge function, you need to first access the vector corresponding to node 'v' and then, into that vector, you need to push the pair (w, weight) [NOTE that, even if we ignore the error that there's only vector, the logic is still incorrect since you're pushing (v, weight) instead of (w, weight) into that vector]. The modified addEdge function would be something like this:
void addEdge(int v, int w, int weight)
{
auto adjacencyList = adj->at(v);
auto sp = std::make_shared<std::pair<int,int>>(std::make_pair(w,weight));
adjacencyList.push_back(sp);
}
Hope this helps you

Can't Save structure content

I have the next problem:
I created the structure:
struct Series : vector<Candle>
{
Security Sec;
int LookFor;
int TF;
int Corrector;
string ID;
int line;
Series(){};
Series (int _lookfor);
void Update();
};
Constructor:
Series::Series (int _lookfor)
{
LookFor=_lookfor;
for (int i = 1; i<=LookFor; i++)
{
Candle cantype = Candle(i);
push_back(cantype);
}
}
So, then we call this construcor it fills object by candle-values. LookFor - is a number of candles in the vector-series.
After initialization i want update this serie (if there is more new candle, i want delete last one and insert new on the begining of vector-serie)
void Series::Update()
{
if (size()==LookFor)
{
if (newer(cantype,c1))
{
Candle cantype = Candle(1);
Candle c1 = at(0);
pop_back();
emplace(begin(),cantype);
}
}
I need to initialize a vector of these series:
vector vec;
vec.push_back(Series(3));
And constructor does its job, everithing is fine.
But then i update them:
for (size_t x =0; x<=size()-1;x++) vec[x].Update();
I have a problem: it cann't save changes in vector. In Update method everithing is fine, it inserts needed candle in itself, but then method is ended - the state of vector (each element of vec) has no changes. In method we see changes, but after it vector become after constructor-like, the state still the same.
Tell me, please, what am I doing wrong?
As others already mentioned, do not derive from these containers (could cause nasty errors like missing dtor calls and memory leaks, no virtual destructor is present in these containers). Instead, add the vector as a member or leave it as is, if you do private inheritance.
You may use the iterator interface for such containers:
for(std::vector<Series>::iterator sIt = vec.begin();sIt != vec.end();++sIt) sIt->Update();
For your task, consider using a deque or a list as a circular buffer instead of the vector for the Candles. It would perform better for insertions and therefore allows you to use push_front() instead of emplace() or insert().
Alternatively, you could hold an index of the vector element just past the last element (which should be the first) and just assign the new candle, et voilĂ , you've got a dense circular buffer.
There are implementations of such circular buffers, for example the one of boost:
http://www.boost.org/doc/libs/1_52_0/libs/circular_buffer/doc/circular_buffer.html
Despite logic issues, which could prevent the modification in certain states, I can't see, why your code doesn't work at all, at least not when I went through the snippets you posted.

STL List copies a struct, but the copied values are offset by two memory addresses

I'm compiling using Code::Blocks on Windows 7 using the MinGW compiler (which I can only assume is the latest version; both Code::Blocks and MinGW were installed this past week). My issue crops up under a particular circumstance, and my attempts to write a simpler script that demonstrates the problem have failed (which implies that there is something wrong with my structure). Also, my apologies for how long this post is.
Currently, I'm rolling with one class, FXSDL, which will act as an SDL wrapper:
class FXSDL
{
public:
FXSDL();
virtual ~FXSDL();
int Initialize();
int Render();
FXID CreateCharacter(FXID hRefID, string fpImage, int wpxTile, int hpxTile, map<int, vector<int> > htAnims);
int SetAnim(FXID hRefID, FXID hAnimID);
FXID hPlayer;
protected:
private:
list<FXSurface> m_lstFXObjects;
list<FXSurface>::iterator m_liFirst;
SDL_Surface* m_lpsfSDLScreen;
Uint32 m_tmOld;
Uint32 m_tmFrame;
};
The value type of my list is:
struct FXSurface
{
FXID hRefID;
int wpxTile;
int hpxTile;
int wpxTotal;
int hpxTotal;
int cntTiles;
map<int, vector<int> > htAnims; // All animations
map<int, vector<int> >::iterator vCurr; // Currently active animation
vector<int>::iterator fiCurr; // Currently active frame
SDL_Surface* lpsfSDL;
SDL_Rect* lprcTiles; // Predefined frame positions
string* fpImage;
};
I've implemented very simple initialize and render function. The CreateCharacter function takes a few parameters, the most important of which is htAnims, a map of integer vectors (idea being: I define numeric ids with easy-to-remember representations, such as FXA_IDLE or FXA_WALK, as the key, and the series of number values representing frames for the animation as a vector). This could be fairly easily implemented as a multidimensional integer array, but animations are variable in length and I want to be able to add new anims (or redefine existing ones) without having to recast an array.
The CreateCharacter function is simple. It creates a new FXSurface, populates it with the required data, and pushes the new FXSurface onto the list:
FXID FXSDL::CreateCharacter(FXID hRefID, string fpImage, int wpxTile, int hpxTile, map<int, vector<int> > htAnims)
{
//list<FXSurface>::iterator lpsfTemp;
FXSurface lpsfTemp;
list<FXSurface>::iterator lpsfPos;
SDL_Rect* lprcCurr = NULL;
int cntTileW = 0;
int cntTileH = 0;
int cntCurr = 0;
// Start off by initializing our container struct
//lpsfTemp = new FXSurface();
lpsfTemp.lpsfSDL = IMG_Load(fpImage.c_str()); // Try to load the requested image
if(lpsfTemp.lpsfSDL != NULL) // If we didn't fail to
{
// Assign some variables for tracking
lpsfTemp.hRefID = hRefID;
lpsfTemp.fpImage = &fpImage;
lpsfTemp.wpxTotal = lpsfTemp.lpsfSDL->w;
lpsfTemp.hpxTotal = lpsfTemp.lpsfSDL->h;
// If a tile width was specified, use it
if(wpxTile != 0)
{
lpsfTemp.wpxTile = wpxTile;
lpsfTemp.hpxTile = hpxTile;
} // Otherwise, assume one tile
else
{
lpsfTemp.wpxTile = lpsfTemp.wpxTotal;
lpsfTemp.hpxTile = lpsfTemp.hpxTotal;
}
// Determine the tiles per row and column for later
cntTileW = lpsfTemp.wpxTotal / lpsfTemp.wpxTile;
cntTileH = lpsfTemp.hpxTotal / lpsfTemp.hpxTile;
// And the total number of tiles
lpsfTemp.cntTiles = cntTileW * cntTileH;
lpsfTemp.lprcTiles = new SDL_Rect[cntTileW*cntTileH];
// So we don't calculate this every time, determine each frame's coordinates and store them
for(int h = 0; h < cntTileH; h++)
{
for(int w = 0; w < cntTileW; w++)
{
cntCurr = (h*cntTileW)+w;
lprcCurr = new SDL_Rect;
lprcCurr->w = lpsfTemp.wpxTile;
lprcCurr->h = lpsfTemp.hpxTile;
lprcCurr->x = w*lpsfTemp.wpxTile;
lprcCurr->y = h*lpsfTemp.hpxTile;
lpsfTemp.lprcTiles[cntCurr] = *lprcCurr;
lprcCurr = NULL;
}
}
// Now acquire our list of animations and set the default
//lpsfTemp.htAnims = new map<int, vector<int> >(*htAnims);
lpsfTemp.htAnims = htAnims;
lpsfTemp.vCurr = lpsfTemp.htAnims.find(FXA_WALK_EAST);
lpsfTemp.fiCurr = lpsfTemp.vCurr->second.begin();
this->m_lstFXObjects.push_back(lpsfTemp);
}
else
{
hRefID = 0;
}
return hRefID;
}
It is precisely as the object is pushed that the error occurs. I've stepped through the code numerous times. Initially, I was only able to tell that my iterators were unable to dereference to the FXSurface object. After using watches to identify the exact memory address that the iterator and list objects pointed to, and dereferencing the address, I noticed the reason for my segfaults: all the values which I put into the original FXSurface were pushed down two memory blocks when the list object copied it!
My process for doing this is simple. I set up a breakpoint at the return statement for CreateCharacter, which gives me a view of lpsfTemp (the FXSurface I later add to the list) and m_lstFXObjects (the list I add it to). I scroll through the members of m_lstFXObjects, which brings me to _M_node, which contains the memory address of the only object I have added so far. I add a watch to this address in the form of (FXSurface)-hex address here-
First, find the address:
(There should be a picture here showing the highlighted _M_node attribute containing the list item's address, but I can't post pictures, and I can only post one URL. The second one is by far more important. It's located at http://www.fauxsoup.net/so/address.jpg)
Next, we cast and deference the address. This image shows both lpsfTemp and the copy in m_lstFXObjects; notice the discrepancy?
http://www.fauxsoup.net/so/dereferenced.jpg - See? All the values are in the correct order, just offset by two listings
I had initially been storing fpImages as a char*, so I thought that may have been throwing things off, but now it's just a pointer and the problem persists. Perhaps this is due to the map<int, vector<int> > I store?
FXSDL has a destructor, but no copy constructor and no assignment operator. Yo you're using naked pointers, but violate the Rule of Three.
I'm not going to look any further.
Use smart pointers to manage resources. Do not put a naked resource into a type, except when that type's only intention is to manage this one resource. From another answer given yesterday:
As a rule of thumb: If you have to manually manage resources, wrap each into its own object.
At a glance, I'd say you're double-deleting lpsfSDL and/or lprcTiles. When you have raw pointers in your structure, you need to follow the rule-of-three (implement copy constructor, assignment operator, and destructor) to properly manage the memory.
These lines look wrong to me:
lprcCurr = new SDL_Rect;
lprcCurr->w = lpsfTemp.wpxTile;
lprcCurr->h = lpsfTemp.hpxTile;
lprcCurr->x = w*lpsfTemp.wpxTile;
lprcCurr->y = h*lpsfTemp.hpxTile;
lpsfTemp.lprcTiles[cntCurr] = *lprcCurr;
lprcCurr = NULL;
lpsfTemp.lprcTiles is a SDL_Rect*. lprcTemp.lprcTiles[cntCurr] is a SDL_Rect. You should be writing this, IMHO:
SDL_Rect tmpRect;
tmpRect.w = lpsfTemp.wpxTile;
tmpRect.h = lpsfTemp.hpxTile;
tmpRect.x = w*lpsfTemp.wpxTile;
tmpRect.y = h*lpsfTemp.hpxTile;
lpsfTemp.lprcTiles[cntCurr] = tmpRect;
Dump the lprcCurr entirely.
Now this code:
lpsfTemp.vCurr = lpsfTemp.htAnims.find(FXA_WALK_EAST);
lpsfTemp.fiCurr = lpsfTemp.vCurr->second.begin();
This is bad. These iterators are invalid as soon as the push_back completes. That push_back is making a copy of lpsfTemp. The map and vector members are going to copy themselves and those iterators will copy themselves but they will be pointing to lpsfTemp's members which are going to be destroyed as soon as CreateCharacter exits.
One way to fix that would be to push_back a FXSurface object at the beginning, use back() to get its reference and operate on that instead of lpsfTemp. Then the iterators would stay consistent and they should stay consistent since you are using a list which does not copy its objects around. If you were using a vector or deque or anything other than a list you would need to manage all those pointers and iterators in the copy constructor and assignment operator.
Another thing: Double and triple check your array bounds when you access that lprcTiles array. Any mistake there and you could be scribbling over who knows what.
I don't know if any of that will help you.