PDA

View Full Version : costructor/destructor problem



mickey
15th February 2007, 09:55
hi, I coded this:


Ne::Ne(): {
printf ("costructor \n");
_w = new double[10];
}

Ne::~Ne() {
printf ("destructor \n");
delete[] _w1;

}
class Lay {
std::vector <Ne> _ne;
...............
}
//in main.cpp
lay._ne.resize(2); //here crash

I can see that when resize is called happen this:


costructor
destructor
destructor
and crash......

I wonder why does 'destructor' start? and 2 times? crash reason maybe can be destroy 2 times the same portion of memory.....but ....
thanks

jacek
15th February 2007, 13:17
I wonder why does 'destructor' start? and 2 times? crash reason maybe can be destroy 2 times the same portion of memory
It's exactly the same problem which I've mentioned in other thread. Implement copy constructor and operator= for Ne and you'll see what's happening.

mickey
15th February 2007, 16:12
Sorry, but maybe the situation is more hard:


class Network {
private:
Lar ilay;
.....................
};

void Network::_create() {
ilay._ne.resize(10);

}
//lay.h
#include "ne.h"
#include <vector>
class Network;
class Lay {
protected:
std::vector <Ne> _ne; //it isn't a pointer
friend Network;
public:
Lay();
~Lay();
};
Lay::Lay {
}
class InputLay : public Lay {
public:
InputLay(){ printf ("cosntructor lay INPUT\n"); };
~InputLay(){ printf ("desntructor lay INPUT\n");};
};

//ne.h
Ne::Ne(): {
printf ("cosntructor\n");
//_w1=0;
_w1 = new double[10];
}

Ne::~Ne() {
printf ("destructor \n");
delete[] _w; //without this works..
}
and it print this:



cosntructor ne
destructor ne
destructor ne

But why does it happen when resize is executed??? why destructor is called 2 times during resize? I don't understand even why it's called!!
It seems me that I haven't done any copy assignment...

jacek
15th February 2007, 16:27
It seems me that I haven't done any copy assignment...
But resize() did. It's defined this way:
void resize( size_type num, const TYPE& val = TYPE() );You can't have empty cells in a vector, so if the resized vector is longer than original one, val will be used to fill those additional cells.

mickey
15th February 2007, 21:49
hi, now it seems ok, but I still have some questions...


Ne& Ne::operator=(const Ne& n) {
printf (" operator = ne \n");
if (this != &n) {
delete [] _w;
_w = new double[10];
*_w = *n._w;
}
return *this;
}

Ne::Ne(const Ne& n): _w(0.5f) {
printf ("cosntructor of copy ne \n");
_w = new double (sizeof n._w);
*_w = *n._w;
}

during resize (it's write previous post), output is this:


cosntructor ne
cosntructor of copy ne
cosntructor of copy ne
cosntructor of copy ne
destructor ne
destructor ne

1. why 3 constructor copy and not 2???
2, I declarede operator= as public; but it doens't print the message; so I thought it isn't necessary; then I declare it as private..but compiler gets me error like 'I can't access private member...' why? it seemed it isn't used.....
3. last: If I don't implement my own operator=, it work fine!!
4. is it necessary in initiazation list of copy costructor _w(0.5) )?
then, It isn't clear if it's used or not...
thanks

jacek
15th February 2007, 22:11
1. why 3 constructor copy and not 2???
Once again take a look at resize() declaration. In STL implementation that comes with GNU libstdc++ it's defined like this:
resize(size_type __new_size, value_type __x = value_type())
First a temporary object will be created (because of TYPE()). That's why you get the first and the last message.
Then val is created using the copy constructor, so you get first message about copy constructor and another one about destructor.
Finally the two new cells are initialized using copy constructor.


Ne::Ne(const Ne& n): _w(0.5f) {
printf ("cosntructor of copy ne \n");
_w = new double (sizeof n._w);
*_w = *n._w;
}
This won't work. sizeof n._w is 4 (on 32-bit systems), because that's the size of a pointer. And why do you initialize _w to 0.5f if it's a pointer? Finally *_w = *n._w will copy only _w[0].

It should be something like:

Ne::Ne( const Ne& n )
: _w( 0 ), _size( n._size )
{
printf ( "cosntructor of copy ne \n" );
_w = new double[ _size ];
for( size_t i = 0; i < _size; ++i ) {
_w[i] = n._w[i];
}
}
Or simply use std::vector<double> and forget about all of the troubles.

mickey
15th February 2007, 23:19
(But I don't see something abiut my second question....)
I guess I have to do the same inside operator= redefinition!
Why do you use _w(0) ??? it isn't necessary (?)
thank you.

jacek
16th February 2007, 00:50
But I don't see something abiut my second question....
operator= isn't used by resize(), but other vector methods might need it.


Why do you use _w(0) ???
Because it's a lot better value than 0.5f.


it isn't necessary (?)
No, it isn't.

mickey
16th February 2007, 00:53
I'm sorry for continue questions but it's happening this strange things:
the program crash on return 1 of main() . It seems desctuctor of ne is called to infinity......it seems like a loop, then it do infinite delete[] _w....
---------------------edited---------------------------
Sorry, I did 'clean solution' and after I compiled again and it doens't crash any more. What can be? Is it normal? thanks

Methedrine
16th February 2007, 03:14
Sorry, I did 'clean solution' and after I compiled again and it doens't crash any more. What can be? Is it normal? thanks

When you build your program inside an IDE (f.e. Visual Studio), it usually just builds the files which have been changed or have not been compiled yet. If you Rebuild your program everything gets compiled again. The difference is, that with a normal build command, it can happen that you keep your old buggy code in the already generated object file and that object file is then linked into your executable, resulting in crashing software (because the bug is still in the object files). I'm too tired right now to remember the rule of thumb we have at our company, but I think it was something along the lines of "as long as you do not change a header file there's no need for a rebuild". I am certain jacek or wysota will gladly correct me on this :cool:

wysota
16th February 2007, 22:57
I am certain jacek or wysota will gladly correct me on this :cool:

I doubt that, we rarely use Visual Studio :) And my rule of thumb is "when using VS, when correcting existing code always rebuild, just in case...". Too much time wasted chasing inexistent bugs...