Receiving segmentation fault in C++ code - c++

I'm using C++, code::blocks (with warnings enabled and I checked to make sure) and SFML.
I've tried hunting the bug down myself but I really can't find what's wrong. I know what a segfault means but this one really has me stumped. I'm a beginner may I add but am quickly learning.
I've got a basic main class void Engine that has a method void RenderFrame that renders every frame of the application. Inside said method I have this code which is supposed to draw all the tiles onto the renderwindow:
Tile* tile;
for (short y = 0; y < mapHeight; ++y) {
for (short x = 0; x < mapWidth; ++x) {
tile = currentLevel -> GetTile(x, y);
if (tile) {
tile -> Draw((x * tileSize), (y * tileSize), Wnd);
}
}
}
The GetTile method is supposed to return a tile from within a std::vector<std::vector<Tile *> >
The Draw method only does this:
void Tile::Draw(int x, int y, sf::RenderWindow *pWnd) {
sprite.SetPosition(x, y);
pWnd -> Draw(sprite);
}
The application compiles just fine, but it crashes right after calling sprite.SetPosition(x, y);
This is the full call stack from the debugger:
#0 68701829 sf::Drawable::SetPosition(float, float) () (D:\Coding\C++\sfml\bin\debug\sfml-graphics.dll:??)
#1 004021F9 Tile::Draw(this=0x76ab8cd5, x=0, y=0, pWnd=0x3e3310) (D:\Coding\C++\sfml\include\Tile.cpp:12)
#2 00401D7E Engine::RenderFrame(this=0x3e3298) (D:\Coding\C++\sfml\include\Engine.cpp:106)
#3 00401B29 Engine::MainLoop(this=0x3e3298) (D:\Coding\C++\sfml\include\Engine.cpp:63)
#4 00401E27 _fu0___ZTIPKc(this=0x3e3298) (D:\Coding\C++\sfml\include\Engine.cpp:119)
#5 004022D6 main() (D:\Coding\C++\sfml\Main.cpp:8)
I hope this is enough information to go on, and thanks in advance.
Edit: Oh, and this is from the debugger output. Program received signal SIGSEGV, Segmentation fault.
In sf::Drawable::SetPosition(float, float) ()
Doesn't give much more information about the problem.

This line in the backtrace looks suspicious:
#1 004021F9 Tile::Draw(this=0x76ab8cd5, x=0, y=0, pWnd=0x3e3310)
This seems to correspond to your Tile::Draw function, except the this pointer is misaligned, which suggests that it's not a valid pointer. So perhaps your std::vector<std::vector<Tile *> > has been corrupted somehow.

The most probable explanation is that the pointer returned by currentLevel->GetTile(x,y) is not valid. This could be because it was not properly initialized (to either NUL or a valid allocated object) or because the object to which it refers has been destroyed. Both would explain that sprite is not a valid object and calling SetPosition on that object will pass an invalid this pointer that would trigger the SIGSEGV.

A general cause of segmentation faults is dereferencing a null or invalid pointer.
1. Check GetTile(), is this causing the fault?
2. Check currentLevel before dereferencing.

Related

Conditional jump or move depends on uninitialised value(s) and Segmentation fault

I'm using a ANN library (kdtree) and I have a problem creating and destroying these objects:
This is my constructor:
myKdtree::myKdtree(vector<Point*> *P){
int nnPts = P->size();
dataPts = annAllocPts(P->size(), DIM);
for (int i = 0; i < P->size(); ++i) {
dataPts[i][0] = P->at(i)->getX();
dataPts[i][1] = P->at(i)->getY();
dataPts[i][2] = P->at(i)->getZ();
i++;
}
kdTree = new ANNkd_tree(dataPts, nnPts, DIM);
}
where dataPts is an ANNpointArray and kdTree is ANNkd_tree*, both objects comming from ANN Library.
The destructor:
myKdtree::~myKdtree(){
annDeallocPts(dataPts);
delete kdTree;
annClose();
}
I create a kdtree, and use it (finding NN and more operations). In some part of the program I have to destroy the kdtree and create it again:
void ElementSet::update(){
if(dataStruct!=NULL) delete dataStruct;
dataStruct = new myKdtree(allpoints);
calcMMD();
}
where dataStruct is abstract object IDataStructure instantiated as myKdtree object.
The first creation of a Kdtree works good. However, when I delete it and create it again, a Segmentation Fault occurs. I can "solve" this Segmentation fault deleting the annDeallocPts(dataPts) from ~myKdtree(). However, I think that this is not the correct solution. I should be able to completely delete the first object, and create it again. Isn't it?
Furthermore, with or without the annDeallocPts(dataPts), Valgrind always shows me the error Conditional jump or move depends on uninitialised value(s) located in the kdTree = new ANNkd_tree(dataPts, nnPts, DIM);, in myKdtree() constructor.
I was looking for a solution in other posts, but I can't find it :(.
Could you help me?
Thanks! :D
You increase i twice in the loop in the constructor, so not all data will be initialized as you skip every second entry. This will lead to undefined behavior if you read the uninitialized (and indeterminate) data from the uninitialized entries in dataPts. Undefined behavior is a common cause of segmentation faults.

VS 2010 C++ Crash when deleting an array of structures

I have a class with a member function mBoundingBox made up of the following struct
typedef struct
{
unsigned int xMin;
unsigned int yMin;
unsigned int xMax;
unsigned int yMax;
} boundingBox;
class CImgProc
{
public:
CImgProc(void);
virtual ~CImgProc(void);
...
boundingBox *mBoundingBox;
...
}
In code I allocate the member:
mBoundingBox = new boundingBox [mBlobCnt];
piddle around with it (don't assign any pointers to it, just using array indexing), then, when I exit I:
if (mBoundingBox != NULL) delete [] mBoundingBox;
and this is causing an error.
Any input?
Updated info. The error does occur at termination in the destructor. The message generated by VS is:
Windows has triggered a breakpoint in ProcImage.exe.
This may be due to a corruption of the heap, ...
This may also be due to the user pressing F12 while ProcImage.exe has focus.
The output window may have more diagnostic information.
I am setting the pointer to NULL in the constructor and then allocating (with new) when I need to. The pointer is valid, but apparently not on the heap (break lands in dbgheap.c).
Once I allocate the memory, I don't happen to do any pointer magic with it. In this case I am looping through an image and gather stats. Then I use the stats stored in this memory to draw back into my image, but, again, in a rather brute force manner, so nothing else makes use of this memory.
It is legal for me to use new to create an array of structs isn't it?
Doh!!! Sorry to waste ya'lls time. I dug back in and discovered that my creation and destruction are fine, but somewhere in the middle I set the value of mBoundingBox[X]. whatever where it turns out X is the dim of the array created.
Typical user error, just a surprising place for the bug to show up.
Most probably you are deleting your array twice. To manage it better use
delete[] mBoundingBox;
mBoundingBox = 0;
instead of
if (mBoundingBox != NULL) delete [] mBoundingBox;
or even better use a smart pointer.
first of all the following check is wrong
if (mBoundingBox != NULL) delete [] mBoundingBox;
new does not returns NULL when it fails to allocate memory, rather it throws an exception.
use nothrow version of "new" if you want to proceed like you are doing. In nothrow version new will return NULL instead of throwing an exception.
mBoundingBox = new (std::nothrow) boundingBox [mBlobCnt];

vector::clear() causing a seg fault

I have a std::vector that is causing some very strange seg faults
//A.h
class A{
private:
std::vector<float> data;
public:
void set(const std::vector<float>& data);
};
//A.cpp
void A::set(const vector<float>& data){
this->data.clear(); // crashes on this line
for(float f : data) this->data.push_back(f);
}
Under what possible circumstances could vector::clear() cause a seg fault? I initially had
void A::set(const vector<float>& data){
this->data = data;
}
and had the same problem. I switched to the above to debug.
This is on gcc 4.7.2, x86_64
IF it crashes precisely at the call to 'data.clear' (I mean, at exactly this line, not somewhere inside the clear), then be sure to check your this pointer at the faulting line.
If somehow your $this is null or trash-value due to accumulated effects of previous bugs, then this line might behave similarily.
On the (almost) other hand, if it actually crashes somewhere inside the clear and you just have cut the stacktrace to make the problem description more succint, then still it is possible to be the same cause.
You may check the 'this' pointer for NULL easily in the debugger. Also, detecting trashvalues is not hard: add some testfields to the A class, fill them in constructor with some predictable BUT NOT CONSTANT values, and when the app crashes, check if the this->mytestvalue is ok. If the $this is trashed, then the pointed test values will very often be almost random.
Likely this is due to stack/memory corruption occurring somewhere else. You should run your program with a memory checker, such as Valgrind using the memcheck tool to see what's going on.

C++ vector of struct with vector in struct causing exception

I got a problem with the following code, which I can't solve since hours...
I'm glad for any kind of advice.
The types are defined as follows:
typedef std::vector< cv::RotatedRect > ds_t;
typedef struct id_ {
std::string path;
std::string fileName;
} id_t;
typedef struct dd_ {
cv::RotatedRect bB;
} dd_t;
typedef std::pair<id_t, std::vector<dd_t> > ts_t;
typedef std::vector<ts_t> tss_t;
Then I try to fill the type with data:
tss_t samples
while (readdir(pDir) != NULL) {
ts_t sample;
sample.first.path = _path;
sample.first.fileName = _name;
ds_t detections;
getDetections(_path, detections); //this only filles the detecions byref
for(size_t i=0; i<detections.size(); i++) {
dd_t data;
data.bB = detections[i];
sample.second.push_back(data); //TODO FIXME
}
samples.push_back(sample);
}
cv::RotatedRect is a very basic class.
class RotatedRect{
public:
RotatedRect();
RotatedRect(const Point2f& _center, const Size2f& _size, float _angle);
void points(Point2f pts[]) const;
Point2f center;
Size2f size;
float angle;
};
bool getDetections(const std::string &imagePath, ds_t &detections)
{
//some processing
for(size_t i=0;i<5;i++)
detections.push_back(RotatedRect(cv::Point2f(110.,110.), cv::Size2f(10.,10.), 90.0f));
return true;
}
Hopefully I copied the whole code and I know, I don't need most of the typedefs...
I have already tried to reserve space sample.second.reserve(detections.size()), but this only postpones the error to samples.push_back.
The erroneous line is indicated by the FIXME, causing "terminate called after throwing an instance of 'std::bad_alloc'"
Thanks for any advice in advance.
std::bad_alloc generally means that you've run out of memory -- possibly because of a leak, or just because you've allocated too much. It can also (rarely) happen due to heap corruption (running off the end of an allocated array or dereferencing a pointer after it has been deleted) or other undefined behavior at some earlier point in the program.
How much memory is your program trying to use at one time? You can try using a leak detector like valgrind to see if there is stuff you should be cleaning up.
edit
The -1 to __builtin_new tells you a lot -- it tells you that someone is calling new with a bogus size. That would probably be a member of std::vector that tries to resize things (you can check the stack trace from valgrind or use a debugger to be sure), which indicates that the vector has been corrupted. Since sample.second is a local (on stack) variable, that tells you that a previous function you called (probably getDetections) overran an onstack buffer or array of some kind and clobbered sample.second. So take a careful look at what that function is doing -- the code you've commented out as //some processing. You can also try using a debugger to set a breakpoint just after sample is created and then set a watchpoint on the memory used by sample.second that is getting corrupted. Then continue the program and it should stop at the point that is clobbering sample.second
It may be helpful to read your compiler's header files to figure out how it implements std::vector -- there's probably a couple of size_t fields and a pointer field in there.

c++ elusive segmentation fault

Im working on this bit of code and I keep getting a segmentation fault. For the life of me I cant figure out why, I know a segmentation fault is when you try to follow a null pointer, but the thing is, in my code "u->previous" isnt null, neither is "u", I checked. If I change the condition in the while loop to (u != NULL), it will iterate twice before faulting on "u->isGreen", Once again, I checked every iteration to see if u was null.
int extractOptimalPath() {
Node *u = nodes[NUM_NODES - 1];
int i = 0;
while (u != NULL) {
cout << i << endl;
u->isGreen = true;
u = u->previous;
i++;
}
return 0;
}
"nodes" is an array of pointers to actual Node objects. I know for sure that the "u->previous" exists in my nodes and "isGreen" is initialized to false;
Heres the Node class, in case you want to see that:
class Node {
public:
GLfloat x, y, z;
int numLinks;
Node *link1;
Node *link2;
GLfloat distance;
Node *previous;
bool isGreen;
Node(GLfloat x, GLfloat y, Node *link1, Node *link2);
Node(GLfloat x, GLfloat y, Node *link1);
Node();
Node(GLfloat x, GLfloat y);
~Node();
bool dijkstra(Node* graph[], Node *source, Node *target); //returns true if a path to target is found
int dist(Node *n1, Node *n2);
int extractOptimalPath(Node* graph[]);
};
What could be causing the seg fault?
That error isn't just for null pointers, it is a pointer that points to anything invalid. That can be null, but it can also be memory that was freed.
I don't see a copy constructor in Node, while I see pointers and a destructor. So you violated the Rule of Three.
As a result, if you accidently copy a Node, that copy's destructor will result in effects you see now.
Update:
To quickly test for this, add a private copy constructor to your Node class, like this:
class Node {
...
private:
Node(const Node&);
};
If you get compiler errors now, you are making copies. The compiler will point you to the locations where that happens.
You don't need to have a NULL pointer to have a Segmentation Fault, it happens every time you access memory out of your allowed scope. Check the thread What is a segmentation fault?.
Your code isn't sufficient to say what causes a segfault. Most likely u->previous in one of your nodes points to some more or less random place in memory, but it's just a guess.
My guess is that in your constructor of a Node object, the previous pointer is never set to NULL at any point. You should have a point when previous is set to NULL (in your actual code, don't assume the code does this for you automatically). Also, as a tip, try using gdb to step through your code. Another tip, valgrind is usually used to consult memory leaks, but I've used it to successfully pinpoint segfaults as well.