why does it crash?

G

Gernot Frisch

The following code crashes, since the delete[] in ~ds is called on a
wrong thingy... Can you help me out? Why does the temporary object get
destructed before the assignment occours???

Output of that code:
152433<bang>


#define MAX_STRLEN 512
class ds;

class cs // const string handler
{
public:
cs(const char* c) {printf("1");dat = c;}
operator ds() const;
const char* dat;
};

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
~ds() {printf("3");if(dat) delete[]dat; dat=NULL;}
ds& operator=(const cs& a) {printf("4");strcpy(dat, a.dat); return
*this;}
char* dat;
};

cs::eek:perator ds()const {printf("5");ds a;a = *this;return a;}


int main(int argc, char* argv[])
{
ds a = cs("B");
}


--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
 
J

John Harrison

Gernot Frisch said:
The following code crashes, since the delete[] in ~ds is called on a
wrong thingy... Can you help me out? Why does the temporary object get
destructed before the assignment occours???

Output of that code:
152433<bang>


#define MAX_STRLEN 512
class ds;

class cs // const string handler
{
public:
cs(const char* c) {printf("1");dat = c;}
operator ds() const;
const char* dat;
};

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
~ds() {printf("3");if(dat) delete[]dat; dat=NULL;}
ds& operator=(const cs& a) {printf("4");strcpy(dat, a.dat); return
*this;}
char* dat;
};

cs::eek:perator ds()const {printf("5");ds a;a = *this;return a;}


int main(int argc, char* argv[])
{
ds a = cs("B");
}

Lack of a copy constructor in class ds. Assignment operator is missing too.

john
 
G

Gernot Frisch

John Harrison said:
Gernot Frisch said:
The following code crashes, since the delete[] in ~ds is called on a
wrong thingy... Can you help me out? Why does the temporary object get
destructed before the assignment occours???

Output of that code:
152433<bang>


#define MAX_STRLEN 512
class ds;

class cs // const string handler
{
public:
cs(const char* c) {printf("1");dat = c;}
operator ds() const;
const char* dat;
};

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
~ds() {printf("3");if(dat) delete[]dat; dat=NULL;}
ds& operator=(const cs& a) {printf("4");strcpy(dat, a.dat); return
*this;}
char* dat;
};

cs::eek:perator ds()const {printf("5");ds a;a = *this;return a;}


int main(int argc, char* argv[])
{
ds a = cs("B");
}

Lack of a copy constructor in class ds. Assignment operator is missing too.

john

doesn't "ds& operator=(const cs& a)" work? I'm copying from a cs,
don't I?
<blink, blink>
Somehow I don't get it.
 
J

John Harrison

Gernot Frisch said:
John Harrison said:
Gernot Frisch said:
The following code crashes, since the delete[] in ~ds is called on a
wrong thingy... Can you help me out? Why does the temporary object get
destructed before the assignment occours???

Output of that code:
152433<bang>


#define MAX_STRLEN 512
class ds;

class cs // const string handler
{
public:
cs(const char* c) {printf("1");dat = c;}
operator ds() const;
const char* dat;
};

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
~ds() {printf("3");if(dat) delete[]dat; dat=NULL;}
ds& operator=(const cs& a) {printf("4");strcpy(dat, a.dat); return
*this;}
char* dat;
};

cs::eek:perator ds()const {printf("5");ds a;a = *this;return a;}


int main(int argc, char* argv[])
{
ds a = cs("B");
}

Lack of a copy constructor in class ds. Assignment operator is missing too.

john

doesn't "ds& operator=(const cs& a)" work? I'm copying from a cs,
don't I?
<blink, blink>
Somehow I don't get it.

You are also copying when you 'return a;' For that you need to have a ds
copy constructor defined, as the compiler generated one is crashing your
program.

The straightforward method is this

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
ds(const ds& rhs){printf("6");dat=new char[MAX_STRLEN]; strcpy(dat,
rhs.dat);}

but maybe a auto_ptr style copy constructor would be better in this case

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
ds(ds& rhs){printf("6");dat= rhs.dat; rhs.dat = 0;}

That would be more efficient (less memory allocation), and would work for
the code you've quoted, but I've not been following exactly what you are
trying to do, so I'm not sure.

john
 
K

Karl Heinz Buchegger

Gernot said:
doesn't "ds& operator=(const cs& a)" work? I'm copying from a cs,
don't I?
<blink, blink>
Somehow I don't get it.

Gernot, If unsure you can try the following:
Declare a private copy constructor and an assignement operator in
each class, but *don't' implement them


For your class ds, we know that both classes would need both
operations, since there is dynamic memory management going
on.

So modify class ds as follows:

class ds // dynamic string handler
{
public:
ds(){printf("2");dat=new char[MAX_STRLEN]; dat[0]='\0';}
~ds() {printf("3");if(dat) delete[]dat; dat=NULL;}
ds& operator=(const cs& a) {printf("4");strcpy(dat, a.dat); return
*this;}
char* dat;

private:
ds( const cs& Arg ); // not implemented by intention
ds operator=( const ds& Arg ); // not implemented by intention
};

and try to compile again. If somewhere a either a copy constructor
or an assignment operator is needed, the above class will either

* not compile

The copy constructor was used outside the class, but the
compiler cannot allow this, since it is private

* not link

One of the member functions of class ds uses a copy constructor
somewhere. Since it is a member function it has access to all
private functions and thus there is no problem for the compiler.

But since you didn't implement the copy constructor, the linker
will moan for a missing function

So in any case:
Declaring those functions private and not implementing them leaves
you with a diagnosable error if one of them is used somewhere. And
from the way ds is written, we know that they *must not* be used
somewhere.
 
G

Gernot Frisch

private:
ds( const cs& Arg ); // not implemented by intention
ds operator=( const ds& Arg ); // not implemented by intention
};


Very good idea!
It was the copy constructor that was missing. I fixed it and it works
good now, thank you all.
-Gernot
 

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

Similar Threads


Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top