C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Vector resize

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
psc80
Guest





PostPosted: Sat Aug 23, 2003 5:57 pm    Post subject: Vector resize Reply with quote



Hello,

this is my problem:
I have a std::vector<T> , T has a constructor that allocate some memory.
The problem is when I call myVector.resize(10);

Element 0 at B8835C0 Element struct B882D70 vector B882D80
Element 1 at B8835C0 Element struct B882D70 vector B882D84
Element 2 at B8835C0 Element struct B882D70 vector B882D88
Element 3 at B8835C0 Element struct B882D70 vector B882D8C
....

It's a log about the memory of my vector, B8835C0 and B882D70, are
memory element allocated. So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

Am i wrong ?
I didn't see the spec about that, anyone can help me

Psc80


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
White Wolf
Guest





PostPosted: Sun Aug 24, 2003 11:25 pm    Post subject: Re: Vector resize Reply with quote



psc80 wrote:
Quote:
Hello,

this is my problem:
I have a std::vector<T> , T has a constructor that allocate some
memory. The problem is when I call myVector.resize(10);
[SNIP]
It's a log about the memory of my vector, B8835C0 and B882D70, are
memory element allocated. So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

Am i wrong ?
I didn't see the spec about that, anyone can help me

IIRC the Rogue Wave STL did that. It proved to be quite surprising to me;
followed by the feeling that it is quite annoying. However it is absolutely
according to the standard - at least as much as I can say I understand the
standard. ;-)

I would say that it seems to be a premature optimization. Something what
better would be a Policy (hi Andrei!Smile ), _if_ the standard would mandate
such things. However - as we unfortunately know it - adding more (than the
standard) template arguments to the STL containers can create quite a
headache for those who try to use them in a portable way (you do not know
their type) right now I guess we should be happy that it is not a policy.

IMHO the original desing decision was based on the assumption that creating
an object is a more expesinve operation than copying one. This might have
came from a research of that time or from requests from customers. IMHO at
that time it might have been a reasonable assumption that copying is cheaper
than creation. If the objects data is calculated or taken from disk or
other IO operation it certainly will hold true. They could (at that time)
safely assume that copying will not be more expensive than creation.
However I also believe that with the advent of multithreaded programming
(which some believe is a mistake in itself Smile ) this truth vanished. When
we create an object (constructor) we can safely assume (unless our code does
something very silly) that there is only one thread (the creator) accessing
the object. So creation is done in a farely safe environment, without any
locking (sequencing access) involved. However copy operations (copy
assignment or construction) cannot make that assumption about the argument
they copy, so they must use locks on it in a multithreaded environment,
possibly making the copy operation way more expensive than construction.

Another (IMHO less likely) trouble is that there will be an additional
instance of that class lurking around, so if that class represents some sort
of limited resource (for example where only 10 instances are allowed) you
are unlikely to be able to make that resize operation.

As I see it now, this is a classic case shouting for a policy based design.
In addition to all above it is possible that there are individual classes in
a system, which would require different approach for efficiency of this
operation. One class might be cheap to construct while expensive to copy,
and another one might just be the opposite. That suggests that some sort of
type traits (containing either policies or attributes on which a the choice
of a policy can be based) are needed.

--
WW aka Attila



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Sun Aug 24, 2003 11:33 pm    Post subject: Re: Vector resize Reply with quote



On 23 Aug 2003 13:57:49 -0400, psc80 <psc80 (AT) freesheep (DOT) org> wrote:

Quote:
I have a std::vector<T> , T has a constructor that allocate some memory.
The problem is when I call myVector.resize(10);

Element 0 at B8835C0 Element struct B882D70 vector B882D80
Element 1 at B8835C0 Element struct B882D70 vector B882D84
Element 2 at B8835C0 Element struct B882D70 vector B882D88
Element 3 at B8835C0 Element struct B882D70 vector B882D8C
...

It's a log about the memory of my vector, B8835C0 and B882D70, are
memory element allocated. So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

You are effectively calling myVector.resize(10, T()). Elements of a
vector are not required to be default constructable. You could have
used myVector.resize(10, myT). Copy constructing is the obvious
general case.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ivan Vecerina
Guest





PostPosted: Sun Aug 24, 2003 11:43 pm    Post subject: Re: Vector resize Reply with quote

"psc80" <psc80 (AT) freesheep (DOT) org> wrote

.....
Quote:
So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

Am i wrong ?
I didn't see the spec about that, anyone can help me

This is what is supposed to happen.
If you inspect the signature of the vector::resize() function, you
will find that it takes a second parameter with a default value:
void resize(size_type n, T v = T());

If the size of the vector is increased, any items that are appended
to the vector will be copied from the second parameter (which, when
not provided by the caller, will be a default-initialized object).


Regards,
--
http://www.post1.com/~ivec



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ryan Winter
Guest





PostPosted: Mon Aug 25, 2003 9:16 am    Post subject: Re: Vector resize Reply with quote

Hi Psc80,

If you call resize with only one parameter, it creates a instance of
that class, then copy constucts it into each element of the vector. So
unless you are defining your own copy constructor, it will default to
just making copies of all your member variables.

This is usually a bad thing because now you have 10 class instances
containing member variable pointers, all pointing at the same chunk of
memory. When the classes destruct, they will all try and delete the
same memory.

Ryan

psc80 <psc80 (AT) freesheep (DOT) org> wrote

Quote:
Hello,

this is my problem:
I have a std::vector<T> , T has a constructor that allocate some memory.
The problem is when I call myVector.resize(10);

Element 0 at B8835C0 Element struct B882D70 vector B882D80
Element 1 at B8835C0 Element struct B882D70 vector B882D84
Element 2 at B8835C0 Element struct B882D70 vector B882D88
Element 3 at B8835C0 Element struct B882D70 vector B882D8C
...

It's a log about the memory of my vector, B8835C0 and B882D70, are
memory element allocated. So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

Am i wrong ?
I didn't see the spec about that, anyone can help me

Psc80

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
psc80
Guest





PostPosted: Mon Aug 25, 2003 10:33 pm    Post subject: Re: Vector resize Reply with quote

In fact I have checked the code in the stl and it's a copy affected to
my all element.
So in order to avoid this problem I don't allocate a memory ... in
constructor, so my constructor is empty, and I allocate memory for each
element when the resize is finished. In fact I don't anderstand why they
take this decision in the stl (for performance reason surely). But in
my opinion vector.resize should call the constructor for each element,
and if the user don't want this constructor they pass it another that do
nothing. In my case I can't resolve this problem by passing another
constructor to the resize function. So I make my init after the resize.

But not really elegant way ..
thanks for you answer.
psc80

psc80 wrote:
Quote:
Hello,

this is my problem:
I have a std::vector<T> , T has a constructor that allocate some memory.
The problem is when I call myVector.resize(10);

Element 0 at B8835C0 Element struct B882D70 vector B882D80
Element 1 at B8835C0 Element struct B882D70 vector B882D84
Element 2 at B8835C0 Element struct B882D70 vector B882D88
Element 3 at B8835C0 Element struct B882D70 vector B882D8C
...

It's a log about the memory of my vector, B8835C0 and B882D70, are
memory element allocated. So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

Am i wrong ?
I didn't see the spec about that, anyone can help me

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Michiel Salters
Guest





PostPosted: Tue Aug 26, 2003 12:35 am    Post subject: Re: Vector resize Reply with quote

[email]ryan.winter (AT) optusnet (DOT) com.au[/email] (Ryan Winter) wrote in message news:<5dadf782.0308241849.40bd834b (AT) posting (DOT) google.com>...
Quote:
Hi Psc80,

If you call resize with only one parameter, it creates a instance of
that class, then copy constucts it into each element of the vector. So
unless you are defining your own copy constructor, it will default to
just making copies of all your member variables.

You may legally define such a class. It isn't useful, as you noted, but
it's also illegal once you try to use it in a vector. The STL
containers all work on values, and olny values. Values can be copied,
and anything that can't be copied isn't a value and doesn't fit in a
container.

Regards,
--
Michiel Salters

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Aug 26, 2003 6:36 pm    Post subject: Re: Vector resize Reply with quote

"Bo Persson" <bop2 (AT) telia (DOT) com> wrote

Quote:
"White Wolf" <wolof (AT) freemail (DOT) hu> wrote...

IMHO the original desing decision was based on the assumption that
creating an object is a more expesinve operation than copying one.
This might have came from a research of that time or from requests
from customers.

Guess so.

No. One basic principle of the STL is to make as few requirements on
the user types as possible. The interface to vector (and to all of the
containers) is designed so that a default constructor is NOT necessary;
all that is necessary is support for copy and for assignment (which
would be necessary anyway in order to support changing the size of the
vector).

Quote:
IMHO at that time it might have been a reasonable assumption that
copying is cheaper than creation. If the objects data is calculated
or taken from disk or other IO operation it certainly will hold
true. They could (at that time) safely assume that copying will not
be more expensive than creation.

Yes.

No. In this particular case, it is NOT a question of any potential
optimization.

Quote:
However I also believe that with the advent of multithreaded
programming (which some believe is a mistake in itself Smile ) this
truth vanished. When we create an object (constructor) we can
safely assume (unless our code does something very silly) that there
is only one thread (the creator) accessing the object. So creation
is done in a farely safe environment, without any locking
(sequencing access) involved. However copy operations (copy
assignment or construction) cannot make that assumption about the
argument they copy, so they must use locks on it in a multithreaded
environment, possibly making the copy operation way more expensive
than construction.

No, this would be locking at the wrong level. The vector cannot be
made responsible for locking its internal operations, that must be
done by the owner of the vector.

That depends on what operations. The vector is certainly responsible
for any locking within its memory management, to avoid conflicts with
other vectors using the same free space pool. On the other hand, the
client is responsible for locking when several threads access the same
vector; in practice, it couldn't be otherwise with a class with
functions which can return pointers and/or references to its internal
structures.

Quote:
The code that calls mutating operations is responsible for ensuring
that at most one thread at a time does this. It could be pretty
obvious at this level. Could be that this piece of data is only
accessed from one particular thread.

The rule is somewhat stricter: if any thread modifies the vector, and
any other thread accesses it in any way (modification or not), then all
accesses must be protected. Not just the modifications.

Typically, of course, if the vector is accessible by more than one
thread, it will be part of a larger structure, and the locks will be on
this larger structure.

Quote:
Another (IMHO less likely) trouble is that there will be an
additional instance of that class lurking around, so if that class
represents some sort of limited resource (for example where only 10
instances are allowed) you are unlikely to be able to make that
resize operation.

Would such a class really satisfy the requirements for a container
member?

The question is simply whether copy and assignment are supported. In
practice, I cannot conceive of supporting these operations on a class
which manages limited resources, but there may be exceptions.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthew Collett
Guest





PostPosted: Wed Aug 27, 2003 9:22 am    Post subject: Re: Vector resize Reply with quote

In article <bid69v$89v$1 (AT) biggoron (DOT) nerim.net>,
psc80 <psc80 (AT) freesheep (DOT) org> wrote:

Quote:
psc80 wrote:
this is my problem:
I have a std::vector<T> , T has a constructor that allocate some memory.
The problem is when I call myVector.resize(10);

[...] So it seems that the vector call one
constructor and copy the result to all elements instead to call the
constructor for each element when calling resize.

So in order to avoid this problem I don't allocate a memory ... in
constructor, so my constructor is empty, and I allocate memory for each
element when the resize is finished. [...]

But not really elegant way ..

If you are going to put your objects in a vector, they must be copyable.
If they allocate memory, this means that your copy constructor must also
perform that allocation. As a bonus, if you get the copy constructor
right, the original resize() call will automatically work correctly with
no need for an ugly two-stage initialisation.

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
llewelly
Guest





PostPosted: Wed Aug 27, 2003 9:23 am    Post subject: Re: Vector resize Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] writes:
[snip]
Quote:
The question is simply whether copy and assignment are supported. In
practice, I cannot conceive of supporting these operations on a class
which manages limited resources, but there may be exceptions.

boost::shared_ptr<> ?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
White Wolf
Guest





PostPosted: Fri Aug 29, 2003 11:23 am    Post subject: Re: Vector resize Reply with quote

Bo Persson wrote:
[SNIP]
Quote:
IMHO at
that time it might have been a reasonable assumption that copying is
cheaper than creation. If the objects data is calculated or taken
from disk or other IO operation it certainly will hold true. They
could (at that time) safely assume that copying will not be more
expensive than creation.

Yes.

At least I see no other valid reason. _If_ vector resize if called (and
this is the case we talk about) the contained type *must* have a default
constructor - but they have decided to use it only once.

Quote:
However I also believe that with the advent of multithreaded
programming (which some believe is a mistake in itself Smile ) this
truth vanished. When we create an object (constructor) we can
safely assume (unless our code does something very silly) that there
is only one thread (the creator) accessing the object. So creation
is done in a farely safe environment, without any locking
(sequencing access) involved. However copy operations (copy
assignment or construction) cannot make that assumption about the
argument they copy, so they must use locks on it in a multithreaded
environment, possibly making the copy operation way more expensive
than construction.

No, this would be locking at the wrong level. The vector cannot be
made responsible for locking its internal operations, that must be
done by the owner of the vector.

Not talking about vector here! I was talking about (for example) a mad COW
string inside a vector. Something which is (for the right or wrong
reasons - it is still a debate) has synchronization *in* it.

Quote:
The code that calls mutating operations is responsible for ensuring
that at most one thread at a time does this. It could be pretty
obvious at this level. Could be that this piece of data is only
accessed from one particular thread.

Not for the case I have meant.

Quote:
Another (IMHO less likely) trouble is that there will be an
additional instance of that class lurking around, so if that class
represents some sort of limited resource (for example where only 10
instances are allowed) you are unlikely to be able to make that
resize operation.

Would such a class really satisfy the requirements for a container
member?

To answer that I would need to be a language lawyer. :-)

Quote:
One class might be cheap to construct while expensive to copy,
and another one might just be the opposite.

I have a hard time imagining how. Can you give a (reasonable) example?

One example is a COW string inside a class, which initializes it with some
non-null value. Copying this string is more expensive then creating it - if
we are in multithreaded environment. The same kind of no-deep-copy
handle-body kind of thing (with a non-null content) in a single thread is of
course the opposite. Creating it _is_ expensive but the copy is very very
fast.

--
WW aka Attila



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bo Persson
Guest





PostPosted: Sun Aug 31, 2003 5:19 pm    Post subject: Re: Vector resize Reply with quote


"White Wolf" <wolof (AT) freemail (DOT) hu> skrev i meddelandet
news:bilh3m$93h$1 (AT) phys-news1 (DOT) kolumbus.fi...
Quote:
Bo Persson wrote:
[SNIP]
IMHO at
that time it might have been a reasonable assumption that copying
is
cheaper than creation. If the objects data is calculated or
taken
from disk or other IO operation it certainly will hold true.
They
could (at that time) safely assume that copying will not be more
expensive than creation.

Yes.

At least I see no other valid reason. _If_ vector resize if called
(and
this is the case we talk about) the contained type *must* have a
default
constructor - but they have decided to use it only once.

Yes, I have noticed that basic_string, where the value_type must be
POD - meaning cheap to copy, *does* have two versions of resize, while
vector only has one. I don't know why.

Quote:

One class might be cheap to construct while expensive to copy,
and another one might just be the opposite.

I have a hard time imagining how. Can you give a (reasonable)
example?

One example is a COW string inside a class, which initializes it
with some
non-null value. Copying this string is more expensive then creating
it - if
we are in multithreaded environment. The same kind of no-deep-copy
handle-body kind of thing (with a non-null content) in a single
thread is of
course the opposite. Creating it _is_ expensive but the copy is
very very
fast.


Did you notice the word "resonable" in my request? :-)

I belive this is more an argument against COW than anything else. If
it is supposed to be an optimization, but turns out to be a slowdown,
there definitely is something wrong. :-)

The resize supporting bitwise copying is cheap for many simple types,
so we must have that one.


Quote:
WW aka Attila


Bo Persson

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Mon Sep 01, 2003 11:12 am    Post subject: Re: Vector resize Reply with quote

On 31 Aug 2003 13:19:27 -0400, "Bo Persson" <bop2 (AT) telia (DOT) com> wrote:

Quote:
Yes, I have noticed that basic_string, where the value_type must be
POD - meaning cheap to copy, *does* have two versions of resize, while
vector only has one. I don't know why.

You have been fooled by presentation language use. There is no
difference.

void string::resize (size_type n, charT c);
void string::resize (size_type n) { resize(n, charT()); }

void vector::resize (size_type n, T c = T());

In either case there is only one real function which copy constructs
elements from the one supplied.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.