Changing body Velocity results in Segmentation Fault
-
- Posts: 11
- Joined: Mon Feb 22, 2010 11:21 pm
- Contact:
Changing body Velocity results in Segmentation Fault
First of all, the Chipmunk engine is fantastic, it's proving very stable and simple to use, I'm loving it so far. And the forum has been a great help.
I've been playing around with it a bit, and created a small demo in which I could add box objects (by dropping them from the top of the screen onto static "ground" segment). Added a lot of them, no problems at all.
While trying to mimic the "Player" demo, creating a ball that moves by changing it's velocity, over the code where I add box objects, I get occasional crashes, sometimes when I move and collide with some box objects, and occasionally occurring without any collisions existing. The debugger indicates a crash at the line where I change the velocity,
body->v.x = -10.0f;
with a SIGSEV. Placing "assert(body)" right before it doesn't trigger.
I've attempted to compile Chipmunk as a static and dynamic library, and to compile it directly into my code, and results are the same.
It all seems to be related to the movement, because if I disabled the movement and add boxes, while leaving the circle on the scene, it doesn't crash.
Some extra data: I'm using Allegro as a rendering/input library, programming in Code::Blocks using the MingW compiler. Using Chipmunk 5.1.
Any ideas?
I've been playing around with it a bit, and created a small demo in which I could add box objects (by dropping them from the top of the screen onto static "ground" segment). Added a lot of them, no problems at all.
While trying to mimic the "Player" demo, creating a ball that moves by changing it's velocity, over the code where I add box objects, I get occasional crashes, sometimes when I move and collide with some box objects, and occasionally occurring without any collisions existing. The debugger indicates a crash at the line where I change the velocity,
body->v.x = -10.0f;
with a SIGSEV. Placing "assert(body)" right before it doesn't trigger.
I've attempted to compile Chipmunk as a static and dynamic library, and to compile it directly into my code, and results are the same.
It all seems to be related to the movement, because if I disabled the movement and add boxes, while leaving the circle on the scene, it doesn't crash.
Some extra data: I'm using Allegro as a rendering/input library, programming in Code::Blocks using the MingW compiler. Using Chipmunk 5.1.
Any ideas?
-
- Posts: 114
- Joined: Sat Mar 07, 2009 7:23 am
- Contact:
Re: Changing body Velocity results in Segmentation Fault
It doesn't trigger on invalid body pointer. Is there any body removing operation in your code?Placing "assert(body)" right before it doesn't trigger.
- Tam Toucan
- Posts: 141
- Joined: Tue Jun 23, 2009 4:26 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
As ShiftZ says the assert only triggers if the condition is false i.e. if the pointer is NULL it would trigger (it's not a smart macro it just checks true/false).
So you either have a corrupt body pointer, or you have removed the body. Post code samples (use the code tags, sorry personal bugbear ) of how you create and remove your objects.
So you either have a corrupt body pointer, or you have removed the body. Post code samples (use the code tags, sorry personal bugbear ) of how you create and remove your objects.
-
- Posts: 11
- Joined: Mon Feb 22, 2010 11:21 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
Thanks for the replies.
I'm not doing any body or shape removal at any times.
Physics initialization code:
addObjectCircle (circle initialization code):
Box creation code:
Object struct:
I'm not doing any body or shape removal at any times.
Physics initialization code:
Code: Select all
void physicsInitialize(void)
{
cpInitChipmunk();
// Initialize a static body with infinite mass and moment of inertia
// to attach the static geometry to.
staticBody = cpBodyNew(INFINITY, INFINITY);
// Optional. Read the docs to see what this really does.
//cpResetShapeIdCounter();
// Create a space and adjust some of it's parameters.
space = cpSpaceNew();
// Lets set some parameters of the space:
// More iterations make the simulation more accurate but slower
space->iterations = 10;
// These parameters tune the efficiency of the collision detection.
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpSpace
cpSpaceResizeStaticHash(space, 30.0f, 1000);
cpSpaceResizeActiveHash(space, 30.0f, 1000);
// Give it some gravity
space->gravity = cpv(0, 90);
cpShape *shape;
Vector2 screenDimensions = Graphics::getPtr()->getScreenDimensions();
// Create some segments around the edges of the screen.
shape = cpSegmentShapeNew(staticBody, cpv(0,0), cpv(0,screenDimensions.y), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddStaticShape(space, shape);
shape = cpSegmentShapeNew(staticBody, cpv(0,screenDimensions.y), cpv(screenDimensions.x,screenDimensions.y), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddStaticShape(space, shape);
shape = cpSegmentShapeNew(staticBody,cpv(screenDimensions.x,screenDimensions.y), cpv(0,screenDimensions.y), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddStaticShape(space, shape);
// add player
Vector2 playerPos(200,200), playerSize(15,15);
//addObjectBox("player1", playerPos, playerSize, 0, false);
addObjectCircle("player1", playerPos, playerSize.x, false);
}
Code: Select all
void addObjectCircle(std::string name, Vector2 pos, float radius, bool isStatic)
{
Object newObject;
newObject.name = name;
// Set up the player
newObject.physBody = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY));
//newObject.physBody = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 0, radius, cpvzero)));
newObject.physBody->p = cpv(pos.x, pos.y);
//newObject.physBody->velocity_func = playerUpdateVelocity;
newObject.physShape = cpSpaceAddShape(space, cpCircleShapeNew(newObject.physBody, radius, cpvzero));
newObject.physShape->e = 0.0f;
newObject.physShape->u = 1.0f;
//newObject.physShape->collision_type = 1;
objectList.push_back(newObject);
}
Code: Select all
void addObjectBox(std::string objectName, Vector2 pos, Vector2 dimensions, float angleRadians, bool isStatic)
{
Object newObject;
newObject.name = objectName;
std::vector<cpVect> verticesList = getVerticesForBox(dimensions);
// Create a box and initialize some of its parameters.
newObject.physBody = createBodyWithParameters(verticesList, pos);
cpSpaceAddBody(space, newObject.physBody);
newObject.physShape = createShapePolyWithParameters(verticesList, Vector2(0,0), newObject.physBody);
cpSpaceAddShape(space, newObject.physShape);
// Add a collision callback between objects of the default type and the box.
//cpSpaceAddCollisionPairFunc(space, 1, 0, &collFunc, &some_value);
cpBodySetAngle(newObject.physBody, angleRadians);
// add Object to object list
objectList.push_back(newObject);
}
std::vector<cpVect> getVerticesForBox(Vector2 dimensions)
{
return getVerticesForBox(dimensions, Vector2(0,0));
}
std::vector<cpVect> getVerticesForBox(Vector2 dimensions, Vector2 offset)
{
std::vector<cpVect> verticesList;
verticesList.push_back(cpv((-dimensions.x * 0.5f) + offset.x, (-dimensions.y * 0.5f)+ offset.y));
verticesList.push_back(cpv((-dimensions.x * 0.5f) + offset.x, (dimensions.y * 0.5f) + offset.y));
verticesList.push_back(cpv((dimensions.x * 0.5f) + offset.x, (dimensions.y * 0.5f) + offset.y));
verticesList.push_back(cpv((dimensions.x * 0.5f) + offset.x, (-dimensions.y * 0.5f) + offset.y ));
return verticesList;
}
cpBody* createBodyWithParameters(std::vector<cpVect>& verticesList, Vector2 pos)
{
cpVect* verts = (cpVect*) malloc(sizeof(cpVect) * verticesList.size());
for(unsigned int idxVect = 0; idxVect < verticesList.size(); ++idxVect)
verts[idxVect] = verticesList[idxVect];
cpBody* physBody = cpBodyNew(1.0, cpMomentForPoly(1.0, verticesList.size(), verts, cpvzero));
//cpBody* physBody = cpBodyNew(INFINITY, INFINITY);
physBody->p = cpv(pos.x, pos.y);
return physBody;
}
cpShape* createShapePolyWithParameters(std::vector<cpVect>& verticesList, Vector2 pos, cpBody* bodyToAddTo)
{
cpVect* verts = (cpVect*) malloc(sizeof(cpVect) * verticesList.size());
for(unsigned int idxVect = 0; idxVect < verticesList.size(); ++idxVect)
verts[idxVect] = verticesList[idxVect];
//cpShape* physShape = cpPolyShapeNew(bodyToAddTo, verticesList.size(), verts, cpvzero);
cpShape* physShape = cpPolyShapeNew(bodyToAddTo, verticesList.size(), verts, cpv(pos.x, pos.y));
physShape->e = 0.0;
physShape->u = 1.5;
physShape->collision_type = 1;
return physShape;
}
Code: Select all
typedef struct Object
{
std::string name;
cpBody* physBody;
cpShape *physShape;
Vector2 shapeOffset; // offset of the shape relative to the body
};
How would a body pointer corruption occur, and why in such specific circumstances?So you either have a corrupt body pointer, or you have removed the body.
-
- Posts: 114
- Joined: Sat Mar 07, 2009 7:23 am
- Contact:
Re: Changing body Velocity results in Segmentation Fault
Show please objectList definition and place where you assigning velocity.How would a body pointer corruption occur
-
- Posts: 11
- Joined: Mon Feb 22, 2010 11:21 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
EDIT: ok, the corruption is actually happening with the "body" pointer. I've printed the pointer address at every cycle, and just before the error it changes to another value. Time for more bug tracing
Oh sorry, forgot to include it.
"objectList" is a std::vector of Object, defined globally.
body->v.x is being changed in my main cycle (the "while" cycle below), which resides in my main() function, and is posted below:
P.S.: END_OF_MAIN is required by allegro.
Below, i post my whole program's code, excluding code for libraries (I think the libraries function calls are self explanatory).
Thanks for looking into it
Oh sorry, forgot to include it.
"objectList" is a std::vector of Object, defined globally.
body->v.x is being changed in my main cycle (the "while" cycle below), which resides in my main() function, and is posted below:
Code: Select all
int main(void)
{
try
{
graphicsInitialize();
physicsInitialize();
std::cout << "Hit + to add object\n";
clear_keybuf(); // clear any previous keyboard input
bool cmdExit = false;
bool cmdAddObject = false;
Object* player = getObjectByName("player1");
while(!cmdExit)
{
if(key[KEY_ESC])
cmdExit = true;
if(key[KEY_PLUS_PAD])
cmdAddObject = true;
else
{
if(cmdAddObject)
{
Vector2 pos(320,10);
Vector2 dimensions(20,10);
addObjectBox(pos, dimensions, 0, false);
cmdAddObject = false;
}
}
// player controls
if(key[KEY_LEFT])
{
assert(player);
assert(player->physBody);
player->physBody->v.x = -10.0f; // crash happens either here or below
//cpBodyApplyImpulse(player->physBody, cpv(-10.0f,0), cpvzero);
}
if(key[KEY_RIGHT])
{
assert(player);
assert(player->physBody);
player->physBody->v.x = 10.0f; // crash also happens here
//cpBodyApplyImpulse(player->physBody, cpv(10.0f,0), cpvzero);
}
physicsUpdate(1);
graphicsUpdate();
//rest(100);
}
physicsTerminate();
graphicsTerminate();
}
catch (...) { // catch an error
std::cout << "Caught an exception -- value is: ";
//std::cout << i << "\n";
}
return 0;
}
END_OF_MAIN()
Below, i post my whole program's code, excluding code for libraries (I think the libraries function calls are self explanatory).
Code: Select all
#include <iostream>
#include <vector>
#include <allegro.h>
#include "chipmunk.h"
#include "Graphics/Graphics.h"
#include "Vector/Vector2.h"
#include "Math/Math.h"
#include <cmath>
cpSpace *space;
cpBody *staticBody;
//cpBody *body;
typedef struct Object
{
std::string name;
cpBody* physBody;
cpShape *physShape;
Vector2 shapeOffset; // offset of the shape relative to the body
};
std::vector<Object> objectList;
int some_value = 42;
bool graphicsInitialize();
void graphicsUpdate();
bool graphicsTerminate();
void physicsInitialize(void);
void physicsUpdate(int ticks);
static int collFunc(
cpShape *a, cpShape *b, cpContact *contacts, int numContacts,
cpFloat normal_coef, void *data);
void physicsTerminate(void);
void addObjectBox(Vector2 pos, Vector2 dimensions, float angleRadians, bool isStatic);
void addObjectBox(std::string objectName, Vector2 pos, Vector2 dimensions, float angleRadians, bool isStatic);
void addObjectCircle(std::string name, Vector2 pos, float radius, bool isStatic);
std::vector<cpVect> getVerticesForBox(Vector2 dimensions);
std::vector<cpVect> getVerticesForBox(Vector2 dimensions, Vector2 offset);
//cpBody* createBodyWithParameters(cpVect* verticesList, unsigned int verticesTotal, Vector2 pos); // creates a body with these vertices and pos, but doesn't add it to the space
//cpShape* createShapePolyWithParameters(cpVect* verticesList, unsigned int verticesTotal, Vector2 pos, Vector2 size, cpBody* bodyToAddTo);
cpBody* createBodyWithParameters(std::vector<cpVect>& verticesList, Vector2 pos);
cpShape* createShapePolyWithParameters(std::vector<cpVect>& verticesList, Vector2 pos, cpBody* bodyToAddTo);
Object* getObjectByName(std::string objectName);
bool getObjectIndexByName(std::string objectName, unsigned int& idxObjectFound);
void deleteObjectByName(std::string objectName);
////////////////////////////////
// Main ////////////////////////
////////////////////////////////
int main(void)
{
try
{
graphicsInitialize();
physicsInitialize();
std::cout << "Hit + to add object\n";
clear_keybuf();
bool cmdExit = false;
bool cmdAddObject = false;
Object* player = getObjectByName("player1");
while(!cmdExit)
{
if(key[KEY_ESC])
cmdExit = true;
if(key[KEY_PLUS_PAD])
cmdAddObject = true;
else
{
if(cmdAddObject)
{
Vector2 pos(320,10);
Vector2 dimensions(20,10);
addObjectBox(pos, dimensions, 0, false);
cmdAddObject = false;
}
}
// player controls
if(key[KEY_LEFT])
{
assert(player);
assert(player->physBody);
player->physBody->v.x = -10.0f;
//cpBodyApplyImpulse(player->physBody, cpv(-10.0f,0), cpvzero);
}
if(key[KEY_RIGHT])
{
assert(player);
assert(player->physBody);
player->physBody->v.x = 10.0f;
//cpBodyApplyImpulse(player->physBody, cpv(10.0f,0), cpvzero);
}
physicsUpdate(1);
graphicsUpdate();
//rest(100);
}
physicsTerminate();
graphicsTerminate();
}
catch (...) { // catch an error
std::cout << "Caught an exception -- value is: ";
//std::cout << i << "\n";
}
return 0;
}
END_OF_MAIN()
bool graphicsInitialize()
{
if(system_driver == NULL) // to ensure allegro is only initialed once - http://www.allegro.cc/forums/thread/591306/670840#target
{
allegro_init();
install_timer();
install_keyboard();
}
Graphics::create(640,480,16);
}
void graphicsUpdate()
{
for(unsigned int idxObject = 0; idxObject < objectList.size(); ++idxObject)
{
cpBody* body = objectList[idxObject].physBody;
//std::cout << "body "<< idxObject <<" pos:" << body->p.x <<","<< body->p.y << "\n";
cpShape* shape = objectList[idxObject].physShape;
if(shape == 0)
continue;
//std::cout << "AAAA\n";
assert(shape);
// draw to screen
switch(shape->klass->type)
{
case CP_CIRCLE_SHAPE:
{
float radius = cpCircleShapeGetRadius(shape);
Vector2 pos(body->p.x, body->p.y);
Graphics::getPtr()->drawCircle(pos,radius,Graphics::getPtr()->getColor(Graphics::Colors::Blue));
}
break;
case CP_SEGMENT_SHAPE:
break;
case CP_POLY_SHAPE:
{
Vector2 shapeOffset = objectList[idxObject].shapeOffset;
Vector2 bodyCenter(body->p.x, body->p.y);
cpVect topVect = cpPolyShapeGetVert(shape, 0);
cpVect bottomVect = cpPolyShapeGetVert(shape, 2);
Vector2 halfDims((bottomVect.x - topVect.x) * 0.5f, (bottomVect.y - topVect.y) * 0.5f),
//pos(body->p.x, body->p.y);
pos(shapeOffset.x, shapeOffset.y);
//shapeOffset = Vector2();
float angleRads = body->a;
//Graphics::getPtr()->drawAABB(pos,halfDims,Graphics::getPtr()->getColor(Graphics::Colors::Blue));
//Graphics::getPtr()->drawOBB(pos,halfDims,angleRads,Graphics::getPtr()->getColor(Graphics::Colors::Blue));
Graphics::getPtr()->drawOBB(pos,halfDims,bodyCenter,angleRads,Graphics::getPtr()->getColor(Graphics::Colors::Blue));
}
break;
}
}
//std::cout << "done drawin\n";
Graphics::getPtr()->drawToScreen();
}
bool graphicsTerminate()
{
Graphics::destroy();
allegro_exit();
}
void physicsInitialize(void)
{
cpInitChipmunk();
// Initialize a static body with infinite mass and moment of inertia
// to attach the static geometry to.
staticBody = cpBodyNew(INFINITY, INFINITY);
// Optional. Read the docs to see what this really does.
//cpResetShapeIdCounter();
// Create a space and adjust some of it's parameters.
space = cpSpaceNew();
// Lets set some parameters of the space:
// More iterations make the simulation more accurate but slower
space->iterations = 10;
// These parameters tune the efficiency of the collision detection.
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpSpace
cpSpaceResizeStaticHash(space, 30.0f, 1000);
cpSpaceResizeActiveHash(space, 30.0f, 1000);
// Give it some gravity
space->gravity = cpv(0, 90);
cpShape *shape;
Vector2 screenDimensions = Graphics::getPtr()->getScreenDimensions();
// Create some segments around the edges of the screen.
shape = cpSegmentShapeNew(staticBody, cpv(0,0), cpv(0,screenDimensions.y), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddStaticShape(space, shape);
shape = cpSegmentShapeNew(staticBody, cpv(0,screenDimensions.y), cpv(screenDimensions.x,screenDimensions.y), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddStaticShape(space, shape);
shape = cpSegmentShapeNew(staticBody,cpv(screenDimensions.x,screenDimensions.y), cpv(0,screenDimensions.y), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddStaticShape(space, shape);
// add player
Vector2 playerPos(200,200), playerSize(15,15);
//addObjectBox("player1", playerPos, playerSize * 2, 0, false); // setting the player as a box crashes as well
addObjectCircle("player1", playerPos, playerSize.x, false);
}
void physicsUpdate(int ticks)
{
int steps = 3; // divide velocity by this value
cpFloat dt = 1.0/60.0/(cpFloat)steps;
int i;
//for(int i=0; i<steps; i++){
for(i=0; i<steps; i++)
{
cpSpaceStep(space, dt);
}
// or:
//cpSpaceStep(space, 1.0f/60.0f);
}
void addObjectBox(Vector2 pos, Vector2 dimensions, float angleRadians, bool isStatic)
{
addObjectBox("", pos, dimensions, angleRadians, isStatic);
}
void addObjectBox(std::string objectName, Vector2 pos, Vector2 dimensions, float angleRadians, bool isStatic)
{
Object newObject;
newObject.name = objectName;
std::vector<cpVect> verticesList = getVerticesForBox(dimensions);
// Create a box and initialize some of its parameters.
//newObject.physBody = cpBodyNew(1.0, cpMomentForPoly(1.0, num, verts, cpvzero));
//newObject.physBody->p = cpv(pos.x, pos.y);
newObject.physBody = createBodyWithParameters(verticesList, pos);
cpSpaceAddBody(space, newObject.physBody);
//newObject.physShape = cpPolyShapeNew(newObject.physBody, num, verts, cpvzero);
//newObject.physShape->e = 0.0; newObject.physShape->u = 1.5;
//newObject.physShape->collision_type = 1;
newObject.physShape = createShapePolyWithParameters(verticesList, Vector2(0,0), newObject.physBody);
cpSpaceAddShape(space, newObject.physShape);
// Add a collision callback between objects of the default type and the box.
//cpSpaceAddCollisionPairFunc(space, 1, 0, &collFunc, &some_value);
cpBodySetAngle(newObject.physBody, angleRadians);
// add Object to object list
objectList.push_back(newObject);
}
void addObjectCircle(std::string name, Vector2 pos, float radius, bool isStatic)
{
Object newObject;
newObject.name = name;
// Set up the player
newObject.physBody = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY));
//newObject.physBody = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 0, radius, cpvzero)));
newObject.physBody->p = cpv(pos.x, pos.y);
//newObject.physBody->velocity_func = playerUpdateVelocity;
newObject.physShape = cpSpaceAddShape(space, cpCircleShapeNew(newObject.physBody, radius, cpvzero));
newObject.physShape->e = 0.0f;
newObject.physShape->u = 1.0f;
//newObject.physShape->collision_type = 1;
objectList.push_back(newObject);
}
std::vector<cpVect> getVerticesForBox(Vector2 dimensions)
{
return getVerticesForBox(dimensions, Vector2(0,0));
}
std::vector<cpVect> getVerticesForBox(Vector2 dimensions, Vector2 offset)
{
std::vector<cpVect> verticesList;
verticesList.push_back(cpv((-dimensions.x * 0.5f) + offset.x, (-dimensions.y * 0.5f)+ offset.y));
verticesList.push_back(cpv((-dimensions.x * 0.5f) + offset.x, (dimensions.y * 0.5f) + offset.y));
verticesList.push_back(cpv((dimensions.x * 0.5f) + offset.x, (dimensions.y * 0.5f) + offset.y));
verticesList.push_back(cpv((dimensions.x * 0.5f) + offset.x, (-dimensions.y * 0.5f) + offset.y ));
return verticesList;
}
cpBody* createBodyWithParameters(std::vector<cpVect>& verticesList, Vector2 pos)
{
cpVect* verts = (cpVect*) malloc(sizeof(cpVect) * verticesList.size());
for(unsigned int idxVect = 0; idxVect < verticesList.size(); ++idxVect)
verts[idxVect] = verticesList[idxVect];
cpBody* physBody = cpBodyNew(1.0, cpMomentForPoly(1.0, verticesList.size(), verts, cpvzero));
//cpBody* physBody = cpBodyNew(INFINITY, INFINITY);
physBody->p = cpv(pos.x, pos.y);
return physBody;
}
cpShape* createShapePolyWithParameters(std::vector<cpVect>& verticesList, Vector2 pos, cpBody* bodyToAddTo)
{
cpVect* verts = (cpVect*) malloc(sizeof(cpVect) * verticesList.size());
for(unsigned int idxVect = 0; idxVect < verticesList.size(); ++idxVect)
verts[idxVect] = verticesList[idxVect];
//cpShape* physShape = cpPolyShapeNew(bodyToAddTo, verticesList.size(), verts, cpvzero);
cpShape* physShape = cpPolyShapeNew(bodyToAddTo, verticesList.size(), verts, cpv(pos.x, pos.y));
physShape->e = 0.0;
physShape->u = 1.5;
physShape->collision_type = 1;
return physShape;
}
Object* getObjectByName(std::string objectName)
{
unsigned int idxObject = 0;
bool objectFound = getObjectIndexByName(objectName, idxObject);
if(objectFound)
return &objectList[idxObject];
else
return 0;
}
bool getObjectIndexByName(std::string objectName, unsigned int& idxObjectFound)
{
for(unsigned int idxObject = 0; idxObject < objectList.size(); ++idxObject)
{
if(objectList[idxObject].name == objectName)
{
idxObjectFound = idxObject;
return true;
}
}
return false;
}
void deleteObjectByName(std::string objectName)
{
unsigned int idxObject = 0;
if(getObjectIndexByName(objectName, idxObject))
{
Object* obj = &objectList[idxObject];
//if(obj->physBody != 0)
if(obj->physShape != 0)
{
cpSpaceRemoveShape(space, obj->physShape);
//cpSpaceRemoveBody(space, obj->physBody);
cpShapeFree(obj->physShape);
//cpBodyFree(obj->physBody);
obj->physShape = 0;
//obj->physBody = 0;
std::cout << "removed\n";
}
//objectList.erase(objectList.begin() + idxObject);
//delete obj;
}
else
std::cout << "object "<< objectName <<" not found, not removed\n";
}
void physicsTerminate(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
cpBodyFree(staticBody);
}
-
- Posts: 11
- Joined: Mon Feb 22, 2010 11:21 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
I think i've figured it out. It doesn't have to do with Chipmunk, it was my code (as I feared but hoped otherwise ). It's a recurring error for me: create a class instance inside a function, add it to a vector, and forget that it eventually gets erased due to dropping out of that function's scope and thus, Segmentation Fault occurs when accessing it.
Changing the "objectList" declaration from to and creating Objects through and from there one just handling Objects as pointers seems to have fixed it.
Sorry about the confusion and thanks for all the help.
Changing the "objectList" declaration from
Code: Select all
std::vector<Object>
Code: Select all
std::vector<Object*>
Code: Select all
Object* newObject = new Object;
Sorry about the confusion and thanks for all the help.
- Tam Toucan
- Posts: 141
- Joined: Tue Jun 23, 2009 4:26 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
Actually what you are doing is valid, but not best practice. When you create a local object on the stack then yes it disappears when it goes out of scope, but putting it on the vector will take a copy of the object i.e. create a new copy of the object. That's why it's not best practice. You are creating/copying/destroying entire objects. Using the pointer means you create one new object and then copy the pointer into the vector and the original pointer goes out of scope (so it's actually the same thing, but dealing with pointers not entire objects).
However you now need to remember to delete the objects from the vector else you'll get a memory leak (when you have actual objects in the vector their destructor's will be called when the vector goes out of scope).
So whilst that might have fixed the problem it was not the direct cause. I can't see anything obviously wrong with the code you posted (other than the memory leak of the malloc). Is that really the entire code that was crashing? I wouldn't be surprised if this comes back to bite you since I think you've hidden, not fixed, the problem
BTW here's a template I use to clear up vectors of new'ed objects.To use it you would do
However you now need to remember to delete the objects from the vector else you'll get a memory leak (when you have actual objects in the vector their destructor's will be called when the vector goes out of scope).
So whilst that might have fixed the problem it was not the direct cause. I can't see anything obviously wrong with the code you posted (other than the memory leak of the malloc). Is that really the entire code that was crashing? I wouldn't be surprised if this comes back to bite you since I think you've hidden, not fixed, the problem
BTW here's a template I use to clear up vectors of new'ed objects.
Code: Select all
#ifndef UTIL_DELETE_AND_CLEAR_H
#define UTIL_DELETE_AND_CLEAR_H
#include <algorithm>
namespace Util {
//
// Functor to delete object
//
template <class DeletablePtr> class DeleteIt
{
public:
void operator () (DeletablePtr& obj) { delete obj; }
};
//
// Helper function to delete all the objects in a container and clear it
//
template <class Container>
inline void deleteAndClear(Container& container)
{
std::for_each(container.begin(), container.end(), DeleteIt<typename Container::value_type>());
container.clear();
}
} // namespace
#endif
Code: Select all
Util::deleteAndClear(objectList);
- Tam Toucan
- Posts: 141
- Joined: Tue Jun 23, 2009 4:26 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
Are you on Linux? If so get valgrind. Invaluable for tracking down stuff like this.
-
- Posts: 11
- Joined: Mon Feb 22, 2010 11:21 pm
- Contact:
Re: Changing body Velocity results in Segmentation Fault
I hadn't thought of this problem, it has never happened to me. Do you have any suggestions on how to create objects in functions and add it to a vector to avoid it?Tam Toucan wrote:Actually what you are doing is valid, but not best practice. When you create a local object on the stack then yes it disappears when it goes out of scope, but putting it on the vector will take a copy of the object i.e. create a new copy of the object. That's why it's not best practice. You are creating/copying/destroying entire objects. Using the pointer means you create one new object and then copy the pointer into the vector and the original pointer goes out of scope (so it's actually the same thing, but dealing with pointers not entire objects).
EDIT: this thread seems to point out some ways to do this, but is related to C++. I intend to program in C++ anyway, but keep away from boost as long as I can.
Yes, I'm aware of how the deletion of pointers in vectors should be done, just hadn't included any code to clear up memory in the end of the program yet. Thanks for pointing it out and for posting your deletion code, though.Tam Toucan wrote: However you now need to remember to delete the objects from the vector else you'll get a memory leak (when you have actual objects in the vector their destructor's will be called when the vector goes out of scope).
I've just excluded some comments from the entire code.Tam Toucan wrote: So whilst that might have fixed the problem it was not the direct cause. I can't see anything obviously wrong with the code you posted (other than the memory leak of the malloc). Is that really the entire code that was crashing? I wouldn't be surprised if this comes back to bite you since I think you've hidden, not fixed, the problem
Valgrind is excellent, I've used it a bit before, but now I'm on windows, so I'm only using gdb in CodeBlocks. Thanks for the tip.Tam Toucan wrote:Are you on Linux? If so get valgrind. Invaluable for tracking down stuff like this.
Who is online
Users browsing this forum: Heise IT-Markt [Crawler] and 30 guests