|
From: Matt F. <mat...@pr...> - 2002-06-05 01:19:17
|
Sorry about the HTML. Hopefully, this will work better. (I've
edited my original post a little, because I noticed a couple things
which are unclear).
Thanks again for any help you can provide.
Sincerely,
Matt Fiedler
To whom it may concern:
I'm working on a simple ecology simulation which manipulates objects
called Organisms. Each organism has a number of characteristics.
The one most relevant to my problem is a string containing the
Organism's species name.
In the course of the simulation, the program often invokes an
Organism copy constructor/constructor for the purpose of
reproduction. The exact constructor invoked depends on the type of
reproduction taking place. After the constructor is called for
either the second or the third time, a segmentation fault results.
Using the Insight debugger, I have discovered that the error comes
inside string member functions (i.e. it fails while trying to copy
the string). The odd thing is that the constructor works without
problems several times before it crashes with identical input.
I have checked the input data (i.e. the old string from which I am
trying to construct the new string in the new organism) using the
debugger and found it to be normal and uncorrupted in any way. I'm
puzzled as to why the program is crashing while doing something as
simple as initializing one string from another.
I'm pasting the header file of the Organism class and the
implementation of the problem constructor into this post. If any
other code or information would be useful, I'd be happy to provide
it. I'm running Mingw through Dev-C++ 5, beta 3. The version of
Mingw uses GCC 2.95.3-6.
Even if you can't find the exact solution, I'd appreciate it if you
could tell me whether either of these two theories are at all
plausible:
1) There is a problem in the way the Mingw string class allocates
memory and this causes my segfault.
2) I'm mangling memory using pointers somewhere. I don't know how
this could happen because the pointers I use are inside handlers
(shared_ptr's from the Boost library) that handle deletion. The only
other times I use pointers, I am very clearly initializing them to
point to new storage. Moreover, the segfaults don't happen randomly
as if I was simply corrupting memory wily-nily. They always happen in
the same place during the initialization of the same type of object).
3) Some third possibility (I consider this the most likely
explanation, though I am at a loss as to what it would be).
Thank you very much for any help that you can provide.
Sincerely,
Matt Fiedler
First, a few typedefs to be aware of:
typedef matrix<OrgVector> WorldMatrix; /* defines "geographic"
storage type
an OrgMatrix is a vector of vectors of localities, all of the
inside vectors will be
maintained at the same size by means of the World constructor
(matrix is a modified version of the STL
*/
typedef matrix<int> AbioticMatrix; /* allows defintion of an integer
value for each
location in the environment, for example of solar input*/
typedef boost::shared_ptr <ReproSys> ReproPtr; //Pointer to a
reproductive system
typedef boost::shared_ptr <NutriSys> NutriPtr; //Pointer to a
nutritional system
class Organism
{
friend bool operator== (const Organism & lhs, const Organism &
rhs);
public:
//constructors
Organism (); //default constructor
Organism (const Organism & OldOrg); //copy constructor
Organism (const Organism & OldOrg, const int & NewRow, const
int & NewCol);
/* copy constructor with location initialization */
Organism (const string & Name, const int & NewSize, const
NutriPtr & ProtoNutri, const ReproPtr & ProtoRepro);
/* allows initialization from the building blocks of an
organism */
//accessors
bool isAlive () const; //indicates if the organism is alive
string getName () const;
int getRow () const;
int getCol () const;
ReproPtr getReproSys () const;
NutriPtr getNutriSys () const;
int getSize () const;
//life activity functions
//functions to interface with the NutriSys class
void Forage (AbioticMatrix & SolarInput, WorldMatrix &
Environment);
void CheckNutrition ();
//functions to interface with the ReproSys class
void Reproduce (WorldMatrix & Environment);
//functions for interfacing with other organisms
int beEaten ();
const Organism & operator= (const Organism &
rhs); //assignment
private:
//data members
//organism body systems
ReproPtr myReproSys;
NutriPtr myNutriSys;
//organism characteristics
string SpeciesName;
bool Alive;
int myRow, myCol, mySize;
};
A couple of notes about the above definition. ReproPtr and NutriPtr
are typdefs of the boost shared_ptr's. They always initialize
correctly inside the constructor intializer list, as do the other
data members.
Organism::Organism (const Organism & OldOrg, const int & NewRow,
const int & NewCol)
/* Pre: an organism and two integers must be input
Post: an organism idenctical to the old one except for its
location has
been constructed */
: myNutriSys ((OldOrg.myNutriSys)->Clone()), //calls a clone
function which returns a pointer to a new object of the
//correct type (NutriSys and
ReproSys are only base classes, different types
//of systems inherit from them)
myReproSys ((OldOrg.myReproSys)->Clone()),
mySize (OldOrg.mySize),
myRow (NewRow),
myCol (NewCol),
Alive (OldOrg.Alive),
SpeciesName (OldOrg.SpeciesName) <-this seems to be the problem
{
}
Organism::Organism (const Organism & OldOrg)
/* Pre: an organism must be input
Post: an organism idenctical to the old one has been constructed
*/
: myNutriSys ((OldOrg.myNutriSys)->Clone()),
myReproSys ((OldOrg.myReproSys)->Clone()),
SpeciesName (OldOrg.SpeciesName),
myRow (OldOrg.myRow),
myCol (OldOrg.myCol),
Alive (OldOrg.Alive),
mySize (OldOrg.mySize)
{
}
______________________________________________________________
Get Your Free E-mail at http://www.prontomail.com
|