are there any dangers in storing objects in vectors?

R

r.z.

I logged construtor and destructor calls for one of my classes and I
discovered that the constructor was called only once while the destructor
was called 3 times for a single object.

I have a vector of objects of class A:
vector<A> vector_of_As;

and I put objects to it like this:
vector_of_As.push_back( A() );

vector_of_As is local so it dies naturally, while As deallocate some memory
in their destructors. Can multiple calls to the destructor of A cause
program crash?
 
J

Jim Langston

r.z. said:
I logged construtor and destructor calls for one of my classes and I
discovered that the constructor was called only once while the destructor
was called 3 times for a single object.

I have a vector of objects of class A:
vector<A> vector_of_As;

and I put objects to it like this:
vector_of_As.push_back( A() );

vector_of_As is local so it dies naturally, while As deallocate some
memory in their destructors. Can multiple calls to the destructor of A
cause program crash?

Also log your copy and assignment constructors. Copies are being made and
destroyed, but you're not logging their creation since you don't have custom
copy and assignment constructors.

Using the default copy and assignment constructions can cause problems if
your constructor or class allocates memory itself. For instance, the
following class can cause problems:

class Foo
{
public:
Foo() { Bar = new int[100]; }
~Foo() { delete[] Bar; }
private:
int* Bar;
};

What will happen is when a copy is made it is a shallow copy by default,
therefore in the new copy Bar is copied as a pointer. So the new copy
points to the same memory as the original. When the copy is destroyed, the
destructor is called, which releases the memory it's Bar is pointing to, but
which the original also points to. So the originals Bar pointer will now be
invalid, it is pointing to memory that has been freed.

If your class does not allocate memory itself, say Bar was just an int, then
it is fine. Look up the "rule of three".
 
R

r.z.

What will happen is when a copy is made it is a shallow copy by default,
therefore in the new copy Bar is copied as a pointer. So the new copy
points to the same memory as the original. When the copy is destroyed,
the destructor is called, which releases the memory it's Bar is pointing
to, but which the original also points to. So the originals Bar pointer
will now be invalid, it is pointing to memory that has been freed.

If your class does not allocate memory itself, say Bar was just an int,
then it is fine. Look up the "rule of three".

Thanks for this small lecture. I was in a situation that you described -
intuitively I changed vector of objects to vector of pointers to objects,
which fixed the problem, but I wasn't fully aware of it until now.
 
M

Mark P

Jim said:
Also log your copy and assignment constructors. Copies are being made and
destroyed, but you're not logging their creation since you don't have custom
copy and assignment constructors.

There's no such thing as an assignment constructor and there's no need
to log the copy assignment operator. Of course the copy constructor,
and any other constructors, would need to be logged to maintain an
accurate count.
 
A

ajk

I logged construtor and destructor calls for one of my classes and I
discovered that the constructor was called only once while the destructor
was called 3 times for a single object.

I have a vector of objects of class A:
vector<A> vector_of_As;

and I put objects to it like this:
vector_of_As.push_back( A() );

vector_of_As is local so it dies naturally, while As deallocate some memory
in their destructors. Can multiple calls to the destructor of A cause
program crash?

when you enter objects in the vector you are calling the copy ctor of
A so you are creating copies of the objects. that is the reason why
you get multiple calls - although not same A instance

-ajk
 
R

Roland Pibinger

intuitively I changed vector of objects to vector of pointers to objects,

Make the (unimplemented) copy constructor and the assignment operator
private to prevent accidental copying. Moreover, STL containers,
iterators and algorithms are designed only for values, not objects.
You will encounter 'impedance mismatches' when you use them for
(pointers to) objects.

Best wishes
Roland Pibinger
 
J

Jacek Dziedzic

Roland said:
> Moreover, STL containers,
iterators and algorithms are designed only for values, not objects.
You will encounter 'impedance mismatches' when you use them for
(pointers to) objects.

Can you explain that? I always thought it would be fine to
store objects in stl containers, as long as these objects
behaved in the manner the containter expected them to
(copyable, assignable, etc.).

I understand the literal meaning of "impedance mismatch",
but I can't draw an analogy, can you describe what you mean?

TIA,
- J.
 
A

Andre Kostur

(e-mail address removed) (Roland Pibinger) wrote in

Make the (unimplemented) copy constructor and the assignment operator
private to prevent accidental copying. Moreover, STL containers,
iterators and algorithms are designed only for values, not objects.
You will encounter 'impedance mismatches' when you use them for
(pointers to) objects.

Why you would you possibly think that STL containers _aren't_ for objects?
They're not idea for pointers to dynamically allocated objects (only
because they don't help you with the lifetime issue, but they'll be happy
to store them), but they're perfectly fine for objects. Including some of
the RAII-style objects (std::auto_ptr being one of the exceptions).
 
R

red floyd

Jacek said:
Can you explain that? I always thought it would be fine to
store objects in stl containers, as long as these objects
behaved in the manner the containter expected them to
(copyable, assignable, etc.).

Roland has a well known prejudice against using the Standard containers.
for pointers. This is neither good nor bad, it's just his opinion and
he's entitled to it.
 
R

Roland Pibinger

Can you explain that? I always thought it would be fine to
store objects in stl containers, as long as these objects
behaved in the manner the containter expected them to
(copyable, assignable, etc.).

I understand the literal meaning of "impedance mismatch",
but I can't draw an analogy, can you describe what you mean?

One needs to distinguish between objects and values. Objects are
characterized by identity, state and behavior whereas values are
transient and do not have significant identity (e.g. dates and
strings), see:
http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedIdioms.pdf.
Objects are non-copyable (it makes no sense to duplicate objects),
values support copying (values are substitutable).
STL was designed with "value semantics" in mind, i.e. only for values,
not for (pointers to) objects. The "impedance mismatch" pops up when
you try to use STL for (pointers to) objects. It works with some
workarounds and limitations but not as smoothly and 'natural' as
libraries that were designed for objects in the in the first place.
 
S

SasQ

Dnia Sun, 01 Apr 2007 09:43:32 +0000, Roland Pibinger napisa³(a):
STL was designed with "value semantics" in mind, i.e. only
for values, not for (pointers to) objects.

But isn't pointers a values? :7
The "impedance mismatch" pops up

What is "impedance mismatch"?
 
R

Roland Pibinger

Why you would you possibly think that STL containers _aren't_ for objects?

You see it when you look at the interfaces of containers, iterators
and algorithms (if not search for 'STL value semantics').
They're not idea for pointers to dynamically allocated objects (only
because they don't help you with the lifetime issue, but they'll be happy
to store them), but they're perfectly fine for objects. Including some of
the RAII-style objects (std::auto_ptr being one of the exceptions).

'Smart pointers' imitate real pointers, the 'impedance mismatch' is
the same.
 
A

Andre Kostur

(e-mail address removed) (Roland Pibinger) wrote in

You see it when you look at the interfaces of containers, iterators
and algorithms (if not search for 'STL value semantics').

You'll need to be clearer in what you're trying to say. I don't see
anything in the interfaces of containers, iterators, and algorithms to
suggest that they aren't appropriate for objects.

Whups.. typo.. "They're not _ideal_ for pointers ..."
'Smart pointers' imitate real pointers, the 'impedance mismatch' is
the same.

You'll need to stop using the phrase "imedance mismatch". It apparently
doesn't mean what I think it might mean, so please explain what you mean by
"impedance mismatch". Also, smart pointers do not "imitate real
pointers". They include most of the interface to real pointers
(dereferencing and such), but also have some extra behaviours that make
them distinctly different than real pointers (depending on the specific
smart pointer, they may include reference counting, auto-destruction of the
pointed-to object, auto-destruction of the pointed to array, and others)
 
B

BobR

SasQ said:
Dnia Sun, 01 Apr 2007 09:43:32 +0000, Roland Pibinger napisa³(a):


But isn't pointers a values? :7


What is "impedance mismatch"?

Impedance: n. A measure of the opposition to the flow of an electric
current, especially in an alternating current circuit.

So, it seems to be off-topic in this NG since it has to do with hardware!
<G>
 

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,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top