Topic: Behavior of STL container with pointers.
Author: Valentin Bonnard <bonnard@clipper.ens.fr>
Date: 1999/02/07 Raw View
Khalid Rizvi wrote:
> Quick and basic question:
>
> If I have vector of pointer to an int, say vector<int*>. On invoking clear
> on vector. int* destructor is never called.
It is. You have to understand that, unlike a reference, a pointer
is a normal object with _value_ semantic, not reference semantic.
You can copy it, read it. Destruction of a pointer is a NOP (and
yes you can call the destructor for a pointer with the object.~T ()
syntax !)
{
int * p = new int (3);
int * q = p; // fresh copy of p, but same referent as p
delete q; // both p and q have illegal values now
// q is destructed (NOP)
// p is destructed (NOP)
}
Imagine what would happen if the destructor for a pointer called
delete on that pointer: the memory would be desallocated three
times, leading to undefined behaviour !
A vector<T> always properly destroy all T objects in it. For
pointers it means doing a NOP.
The semantics of vector<T> doesn't depends on the type T
(hopefully).
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Silvio Bierman" <sbierman@idfix.nl>
Date: 1999/02/07 Raw View
No general STL container can make the assumption that pointer elements are
to be deleted or are even allocated by new. You can either build your own
container, use auto_ptr or reference counting elements or explicitly delete
the pointers before removing them from the container.
Silvio Bierman
Khalid Rizvi wrote in message <79c4vg$pf5@bgtnsc03.worldnet.att.net>...
>
>If I have vector of pointer to an int, say vector<int*>. On invoking clear
>on vector. int* destructor is never called.
...
>My understanding has been that erase() of container would not only delete
>the link of iterator from container, but would be smart enough to free the
>memory too.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Khalid Rizvi" <khalid.rizvi@worldnet.att.net>
Date: 1999/02/04 Raw View
Quick and basic question:
If I have vector of pointer to an int, say vector<int*>. On invoking clear
on vector. int* destructor is never called.
// ----------
#include <iostream>
#include <vector>
using namespace std;
class Integer
{
public:
Integer(int i=999)
: m_int(i)
{}
virtual ~Integer()
{
cout << "Destructor of " << m_int << " called" << endl;
}
private:
int m_int;
};
int main()
{
vector<Integer*>* pvec = new vector<Integer*>();
for (int i = 0; i < 1000; i++)
pvec->push_back(new Integer(i));
// When I wanted to delete the vect, I called clear on pvec, which would
// internally
// call erase(begin(), end()). I wanted that. I also assumed that
// internal implementationof
// pvec->erase(iterator) would be to invoke the delete operator on
// pointer to int
pvec->clear(); // expect to see "Destructor of " message, but do not
delete pvec;
// I did not see the STL code going inside the destructor of Integer,
// Why?
// Then I did as follows:
// vector<Integer*>::iterator iter= pvec->begin();
// for (; iter != pvec->end(); iter++)
// delete (*iter);
// This, by force deleted all the inter pointers.
return 0;
}
My understanding has been that erase() of container would not only delete
the link of iterator from container, but would be smart enough to free the
memory too.
Any help or pointer to some info will be highly appreciated:.
Thanks
Khalid.
----
Imagination is more important than knowledge
-- Einstein
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/05 Raw View
In article <79c4vg$pf5@bgtnsc03.worldnet.att.net>, Khalid Rizvi
<khalid.rizvi@worldnet.att.net> writes
>My understanding has been that erase() of container would not only delete
>the link of iterator from container, but would be smart enough to free the
>memory too.
It doesn't and IMO should not. There is no reason that a vector of
pointers should own the objects pointed to. If you want that you must
provide an appropriate smart pointer (and auto_ptr isn't it)
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1999/02/05 Raw View
Khalid Rizvi wrote:
> Quick and basic question:
>
> If I have vector of pointer to an int, say vector<int*>. On invoking clear
> on vector. int* destructor is never called.
It's your responsibility to call delete on the pointer. STL containers destroy
the object they contain. In your case, the container contains a pointer so it
destroys the pointer. It's up to you to delete that to which the pointer points,
preferably before you tell the container to destroy its object. STL conatainers
have no special knowledge of its containing object. You could design your own
container classes to specifically take pointers to objects and then delete the
objects pointed to as well as the pointer itself when the container was cleared
or being destroyed ( Borland did that in their own container classes prior to
the STL ), but that's up to you and is not a part of the STL.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/02/05 Raw View
Khalid Rizvi wrote:
>
> Quick and basic question:
>
> If I have vector of pointer to an int, say vector<int*>. On invoking clear
> on vector. int* destructor is never called.
Oh yes, int* destructor _is_ called. Just that the int* destructor
is a simple do-nothing.
If the int* destructor would delete the pointer, code like the
following would cause dangling pointers:
void foo(int*);
void bar()
{
int* p = new int;
foo(p); // would delete argument on destruction
// p now would be a dangling pointer
} // and at this point, o would get deleted as well!
Moreover, the following code would fail:
void baz()
{
int i;
int* p=&i;
} // destruction of p would try to delete the local variable!
So if you think about it, it's good that pointers don't delete
(auto_ptr does; the second example would have problems with
auto_ptr as well; the first one wouldn't, because the copied
pointer would go to NULL and therefore not be dangling.
Esp. there would be no second destruction.
Using smart pointers in your container helps (do *not*
use auto_ptr; it isn't guaranteed to work). However, with
int, every type of pointer is overkill.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]