Debugging at runtime

C

Cleverbum

Hi,
I'm a complete beginner, having written my second program and finally
got it to compile, I've got an error I can't track down occurring at
runtime - basically whatever I do it says Segmentation Fault.
I was wondering if there was any way I could get a slightly more
verbose description of the error so that I could think about sorting it
out.

Someone mentioned to me that the g++ option -DRANGE_CHECKING would
check if i was accessing uninitialised arrays or something at compile
time, but that hasn't helped, Thanks in advance, I'm really at my wits
end!
 
P

Phlip

Cleverbum said:
I'm a complete beginner, having written my second program and finally
got it to compile, I've got an error I can't track down occurring at
runtime - basically whatever I do it says Segmentation Fault.

This newsgroup is only qualified to discuss C++ source; not all its various
implementations and tools, including debuggers.

You could post some source here - most seg faults are easy to spot - or you
could post your question about debugging to a g++ newsgroup.
 
C

Cleverbum

seems the compiler newsgroups are only posted to every couple of days
or so, so I may as well post the code here, been through it a few times
myself and have had no luck in spotting anything untoward:

/* models particle(s) settling under gravity in three dimensions.
also includes inter-particle gravity */

#include <iostream>
#include <math.h>
#include <fstream>
#include <sstream>
#include <string>
#include <time.h>
using namespace std;

const int n = 1; // number of particles
const double G = 6.6742e-11; // universal gravitational constant
const double gravity = 9.81; // freefall acceleration due to gravity
const int max_time =100;
const int timeStep = 1;

struct vec_3d{
double x, y, z;
};

class particle{
// all vectors stored as arrays [0]=x dir [1]=y dir [2]=z dir
private:
double* pos;
double* vel;
double* frc;
double mass;
bool hard;
double rad;
public:
particle(){
srand(time(0));
int randint = 0;
for(int i=0;i<3;i++){
randint = rand()%1000;
pos = randint / 1000.0;
vel=0.0;
frc=0.0;
}
mass=1.0;
rad=1.0;
hard=true;
}

//void move(double*); // speeds supplied as array
//void move(vec_3d); // speeds supplied as vector structure
void move(); // uses speeds saved within particle object

//void accelerate(double*); // forces supplied as array
//void accelerate(vec_3d); // forces supplied as vector
void accelerate(); // uses forces stored inside particle object

string toString(){
ostringstream os;
os << pos[0] << '\t'
<< pos[1] << '\t'
<< pos[2] << '\t'
<< vel[0] << '\t'
<< vel[1] << '\t'
<< vel[2] << '\t';
return os.str();
} ;

friend void calculate_forces(particle, particle);
friend void single_particle_forces(particle);
};

main(){
particle* myParticles = new particle[n];
for(int simulation_time=0;simulation_time<max_time; simulation_time
+= timeStep){
for(int i=0; i<n; i++){
if(n>1){
for(int j=i+1; j<n; j++){
calculate_forces(myParticles, myParticles[j]);
}
}
single_particle_forces(myParticles);
myParticles.accelerate();
myParticles.move();
cout << i << myParticles.toString();
}
}

}

void particle::move(){
for(int j=0;j<3;j++){
pos[j] += vel[j] * timeStep;
}
}

void particle::accelerate(){
for(int j=0;j<3;j++){
vel[j] += frc[j] * timeStep;
}
}

void calculate_forces(particle x, particle y){
for(int i=0;i<3;i++){
//Gravitational attraction between the bodies
int mySign; //used to determine direction of force
if(y.pos>x.pos){mySign = -1;} else {mySign = 1;}
x.frc = mySign * G * x.mass * y.mass / (( y.pos - x.pos)*(
y.pos - x.pos));
y.frc = -1 * mySign * G * x.mass * y.mass / (( y.pos -
x.pos)*( y.pos - x.pos));
}
}
void single_particle_forces(particle x){
//gravity acts negative on z axis
x.frc[2] -= x.mass * gravity;
}
 
V

Victor Bazarov

seems the compiler newsgroups are only posted to every couple of days
or so, so I may as well post the code here, been through it a few
times myself and have had no luck in spotting anything untoward:

[...]

class particle{
// all vectors stored as arrays [0]=x dir [1]=y dir [2]=z dir
private:
double* pos;
double* vel;
double* frc;
double mass;
bool hard;
double rad;
public:
particle(){
srand(time(0));
int randint = 0;
for(int i=0;i<3;i++){
randint = rand()%1000;
pos = randint / 1000.0;


'pos' pointer has never been initialised. You're dereferencing
an uninitialised (invalid) pointer.

vel=0.0;
frc=0.0;
}
mass=1.0;
rad=1.0;
hard=true;
}

[...]
};

main(){


int main(){

V
 
C

Cleverbum

big words, worked out what they meant though and no longer getting the
segmentation fault, thanks.
 
M

Mike Wahler

seems the compiler newsgroups are only posted to every couple of days
or so, so I may as well post the code here, been through it a few times
myself and have had no luck in spotting anything untoward:

As Phlip predicted, the problem is easy to spot:
/* models particle(s) settling under gravity in three dimensions.
also includes inter-particle gravity */

#include <iostream>
#include <math.h>
#include <fstream>
#include <sstream>
#include <string>
#include <time.h>
using namespace std;

const int n = 1; // number of particles
const double G = 6.6742e-11; // universal gravitational constant
const double gravity = 9.81; // freefall acceleration due to gravity
const int max_time =100;
const int timeStep = 1;

struct vec_3d{
double x, y, z;
};

class particle{
// all vectors stored as arrays [0]=x dir [1]=y dir [2]=z dir

Why not use std::vectors? Had you done so (and used them correctly),
you would not have been bit by your misunderstanding about the
difference between arrays and pointers (you should avoid pointers
in C++, there is almost always a better way).

private:
double* pos;
double* vel;
double* frc;

'pos' 'vel' and 'frc' are *not* arrays, they are pointers. Until
you give them valid values (the addresses of memory that belongs
to your program), accessing their values or dereferencing them
will give undefined behavior (on some systems, manifest as
'segmentation faults')

You need to allocate some memory and assign its address to your
pointers. But better yet, use std::vectors instead.
double mass;
bool hard;
double rad;
public:
particle(){
srand(time(0));
int randint = 0;
for(int i=0;i<3;i++){
randint = rand()%1000;
pos = randint / 1000.0;


Here's the first instance of undefined behavior. You're trying
to access memory at address pos+i. But this will be a random,
unpredictable 'value'.
vel=0.0;
frc=0.0;


And again, and again.
}
mass=1.0;
rad=1.0;
hard=true;
}

//void move(double*); // speeds supplied as array
//void move(vec_3d); // speeds supplied as vector structure
void move(); // uses speeds saved within particle object

//void accelerate(double*); // forces supplied as array
//void accelerate(vec_3d); // forces supplied as vector
void accelerate(); // uses forces stored inside particle object

string toString(){
ostringstream os;
os << pos[0] << '\t'
<< pos[1] << '\t'
<< pos[2] << '\t'
<< vel[0] << '\t'
<< vel[1] << '\t'
<< vel[2] << '\t';

And again, and again ...
return os.str();
} ;

friend void calculate_forces(particle, particle);
friend void single_particle_forces(particle);
};

main(){

Main is *required* to be declared as returning type 'int'.
This is *not* optional as in the old version of C.
particle* myParticles = new particle[n];

Now here, you're allocating memory for your pointer 'myParticles'
to point to. This is what should have been done above with your
other pointers. (But again, don't; use std::vectors instead.)
for(int simulation_time=0;simulation_time<max_time; simulation_time
+= timeStep){
for(int i=0; i<n; i++){
if(n>1){
for(int j=i+1; j<n; j++){
calculate_forces(myParticles, myParticles[j]);
}
}
single_particle_forces(myParticles);
myParticles.accelerate();
myParticles.move();
cout << i << myParticles.toString();


Make sure 'i' and 'j' never exceed the value n-1. Hint: What
is the value of 'n' at this point?
}
}

}

void particle::move(){
for(int j=0;j<3;j++){
pos[j] += vel[j] * timeStep;

More invalid memory acesses, resulting in undefined behavior.
}
}

void particle::accelerate(){
for(int j=0;j<3;j++){
vel[j] += frc[j] * timeStep;

And more.
}
}

void calculate_forces(particle x, particle y){
for(int i=0;i<3;i++){
//Gravitational attraction between the bodies
int mySign; //used to determine direction of force
if(y.pos>x.pos){mySign = -1;} else {mySign = 1;}
x.frc = mySign * G * x.mass * y.mass / (( y.pos - x.pos)*(
y.pos - x.pos));
y.frc = -1 * mySign * G * x.mass * y.mass / (( y.pos -
x.pos)*( y.pos - x.pos));


And more.
}
}
void single_particle_forces(particle x){
//gravity acts negative on z axis
x.frc[2] -= x.mass * gravity;

And more.


Recommendation: Start *much* smaller. Test each small piece
as you go, don't add more until what you have works as desired.
That's how professionals do it, and so should you.

And again, exploit the standard library. Use std::vectors instead
of arrays. They do all the memory management for you automatically.

HTH,
-Mike
 
M

Mike Wahler

big words, worked out what they meant though and no longer getting the
segmentation fault, thanks.

Those might seem 'big words' to you, but they express
very fundamental concepts. You need to become *very*
familiar with those concepts.

Perhaps your C++ book(s) are of poor quality. Which
one(s) are you using? (See the peer reviews at
www.accu.org for recommendations; including for those
which to avoid).

-Mike
 
N

Noah Roberts

Hi,
I'm a complete beginner, having written my second program and finally
got it to compile, I've got an error I can't track down occurring at
runtime - basically whatever I do it says Segmentation Fault.
I was wondering if there was any way I could get a slightly more
verbose description of the error so that I could think about sorting it
out.

Someone mentioned to me that the g++ option -DRANGE_CHECKING would
check if i was accessing uninitialised arrays or something at compile
time, but that hasn't helped, Thanks in advance, I'm really at my wits
end

Most development environments come with a debugger. Learn to use it.

In environments with g++ it is called gdb and the compiler command line
switch to turn on debugging symbols is -g. Learning to use a debugger
and a profiler are important parts of computer programming and way
beyond the scope of most newsgroups...buy a book...no, I can't
recommend one...there is a gdb book online somewhere...
 
A

andy

seems the compiler newsgroups are only posted to every couple of days
or so, so I may as well post the code here, been through it a few times
myself and have had no luck in spotting anything untoward:

Hi Cleverbum,

BTW I think you need to pass the arguments by refernece in these
functions:

class particle {...
friend void calculate_forces(particle&, particle&);
friend void single_particle_forces(particle&);
};

If you dont you will get a copy of particles passed into the functions
and your original particles will remain unchanged.

I have been implementing a library dealing with physical quantities and
your code is just the type of example I am looking for to test the code
and improve it.

http://tinyurl.com/7m5l8

Anyway FWIW Below ---^--> is what the code would look like in my pqs
library.
(Please note that I have had to modify the library code from the
version of pqs above, by adding an array operator to the three_d vect
class and also removing the constraint on multiplication/divison of
vectors by scalars to arithmetic types only and added assignment
operators (so it wont compile with the latest released version
pqs_3_1_0) but this is just the type of code that can help me find out
what is missing.

I am wondering if it would be OK to use this as an example in a future
version of the pqs library, with due attribution (to Cleverbum?) of
course? ( Note also the license, which is the only one acceptable to
boost FWIW)

regards
Andy Little

-------------------------------------------
// Copyright Cleverbum 2005
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

/*
models particle(s) settling under gravity in three dimensions.
also includes inter-particle gravity
*/

#include <ctime>
#include <iostream>
#include <boost/shared_array.hpp>
#include <boost/pqs/t1_quantity/types/out/length.hpp>
#include <boost/pqs/t1_quantity/types/out/velocity.hpp>
#include <boost/pqs/t1_quantity/types/out/force.hpp>
#include <boost/pqs/t1_quantity/types/out/mass.hpp>
#include <boost/pqs/t1_quantity/types/out/time.hpp>
#include <boost/pqs/t1_quantity/types/out/acceleration.hpp>
#include <boost/pqs/t1_quantity/constants/gravitational_constant.hpp>
#include <boost/pqs/three_d/vect_out.hpp>
#include <boost/pqs/angle/out/angle.hpp>

namespace pqs = boost::pqs;

const int num_particles = 1; // number of particles
const pqs::time_<int>::s max_time(100);
const pqs::time_<int>::s timeStep(1);

class particle{
private:

pqs::three_d::vect<pqs::length::m> pos;
pqs::three_d::vect<pqs::velocity::m_div_s> vel;
pqs::three_d::vect<pqs::force::N> frc;
pqs::mass::kg mass;
bool hard;
// not referenced?
// pqs::angle::rad rad;
public:
particle()
// note frc and vel are default initialised to 0,0,0 in pqs
:mass(1.0)/*,rad(1.0)*/,hard(true)
{
srand(time(0));
pos.x = pqs::length::mm(rand()%1000);
pos.y = pqs::length::mm(rand()%1000);
pos.z = pqs::length::mm(rand()%1000);
}

void move(); // uses speeds saved within particle object

void accelerate(); // uses forces stored inside particle object

std::string toString(){
std::eek:stringstream os;
os << pos.x << '\t'
<< pos.y << '\t'
<< pos.z << '\t'
<< vel.x << '\t'
<< vel.y << '\t'
<< vel.z << '\t';
return os.str();
} ;
friend void calculate_forces(particle&, particle&);
friend void single_particle_forces(particle&);
};


int main(){

// See http://www.boost.org/libs/smart_ptr/shared_array.htm
// for documentation.
boost::shared_array<
particle
> myParticles(new particle[num_particles]);

for( pqs::time_<int>::s simulation_time
= pqs::time_<int>::s(0);
simulation_time < max_time;
simulation_time += timeStep){

for(int i=0; i < num_particles; ++i){
if(num_particles > 1){
for(int j = i+1; j < num_particles; ++j){
calculate_forces(myParticles, myParticles[j]);
}
}
single_particle_forces(myParticles);
myParticles.accelerate();
myParticles.move();
std::cout << i << myParticles.toString();
}

}
}

void particle::move(){
this->pos += this->vel * timeStep;
}

void particle::accelerate(){
this->vel += this->frc / this->mass * timeStep;
}

void calculate_forces(particle& x, particle& y){

for(int i = 0;i < 3;++i){
//Gravitational attraction between the bodies
//used to determine direction of force
int mySign =(y.pos > x.pos)? -1:1;
x.frc = mySign
* pqs::physics::gravitational_constant::G
* x.mass * y.mass / pqs::pow<2>(y.pos - x.pos);
y.frc = -1 * mySign
* pqs::physics::gravitational_constant::G
* x.mass * y.mass / pqs::pow<2>( y.pos - x.pos);
}
}

void single_particle_forces(particle& x){
//gravity acts negative on z axis
x.frc.y -= x.mass * pqs::acceleration::g;
}
 
C

Cleverbum

cheers for the spot on the pass by reference, I was wondering why
nothing was really working...
the other couple of things are that at the moment the code only really
models a kind of wierd ghostly particle which has no hard boundary at
all, over enough time they all occupy the same space, at which point
forces become infinite and particles blast off with infinite
velocities.
I'm working on collision detection and other thing associated with hard
spheres at the moment and can keep you up to date if you'd like?
 
M

mlimber

cheers for the spot on the pass by reference, I was wondering why
nothing was really working...
the other couple of things are that at the moment the code only really
models a kind of wierd ghostly particle which has no hard boundary at
all, over enough time they all occupy the same space, at which point
forces become infinite and particles blast off with infinite
velocities.
I'm working on collision detection and other thing associated with hard
spheres at the moment and can keep you up to date if you'd like?

As previously mentioned, the topic of this groups is the C++ language
itself, not the applications written in it (cf.
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9). If you
have C++ language questions, we may well provide some assistance, but
your particular application is not really topical here and shouldn't
really be the subject of a discussion on this group.

Cheers! --M
 
K

kwikius

(e-mail address removed) wrote:

(Apologies for the late reply)
cheers for the spot on the pass by reference, I was wondering why
nothing was really working...
the other couple of things are that at the moment the code only really
models a kind of wierd ghostly particle which has no hard boundary at
all, over enough time they all occupy the same space, at which point
forces become infinite and particles blast off with infinite
velocities.

Right. I noticed that in the calculate_forces function that if the
particles do occupy the same space then you will get a division by
zero. Therefore I would guess you need to check this before doing the
calculation and presumably set force result to 0 then? I am also
guessing that you mean += in there instead of = :

if(y.pos>x.pos){mySign = -1;} else {mySign = 1;}
x.frc = mySign * G * x.mass * y.mass / (( y.pos - x.pos)*(
//^^^ += ???
y.pos - x.pos));

y.frc = -1 * mySign * G * x.mass * y.mass / (( y.pos -
// ^^^ += ???
x.pos)*( y.pos - x.pos));

Could be wrong of course ... !
I'm working on collision detection and other thing associated with hard
spheres at the moment and can keep you up to date if you'd like?

Yes I would definitely be interested in that thanks.

regards
Andy Little
 
K

kwikius

mlimber said:
As previously mentioned, the topic of this groups is the C++ language
itself, not the applications written in it (cf.
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9). If you
have C++ language questions, we may well provide some assistance, but
your particular application is not really topical here and shouldn't
really be the subject of a discussion on this group.

Surely, the pass by reference issue is important enough to render the
post extremely pertinent? I would guess this to be a common mistake if
your background is Java. I feel that your reaction was a little too
fast in this case .

Also a point of order. IMO you should have put your admonition in reply
to my post, as it was I that made the request to make use of
Cleverbum's code, so any OT'ness is my fault, not his.

regards
Andy Little
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top