Should I use pointer inside container?

G

Goran

Hi @ all!

Again one small question due to my shakiness of what to use...

What is better / smarter?

private:
vector<MyClass_t> * itsVector;

OR...

private:
vector<MyClass_t * > * itsVector;

How works such a stl container? Does it use heap or stack?

Thanks

Goran
 
B

Barry

Goran said:
Hi @ all!

Again one small question due to my shakiness of what to use...

What is better / smarter?

STL contains requires the element to be assignable
as it copy each element you push_xxxx and insert.

So, if your element is not assignable, then you have no other way than
to use pointer as element

when your element is assignable, then you have too choose, the major
principle is that whether your element is big object.
if is then use pointer to avoid copy
private:
vector<MyClass_t> * itsVector;

OR...

private:
vector<MyClass_t * > * itsVector;

How works such a stl container? Does it use heap or stack?

you have to refer to a C++ text book or check out some implementation code.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Hi @ all!

Again one small question due to my shakiness of what to use...

What is better / smarter?

private:
vector<MyClass_t> * itsVector;

OR...

private:
vector<MyClass_t * > * itsVector;

None of the above, use either

std::vector<MyClass> itsVector;

or

std::vector<MyClass*> itsVector;

Which one you should use depends on how you will use the elements, if
you have not special needs the first one is generally preferable since
it removes the need to new and delete the elements manually.

There might be a few legitimate situations where you might need a
pointer to a vector, but I would say that it is most often a sign of bad
design.
How works such a stl container? Does it use heap or stack?

The elements contained in the vector are stored on the heap, notice
thought that for some containers, std::vector among them, the elements
might be re-located when you perform some operations on the containers,
so taking the address of an object can be hazardous.

In fact, I would say that when you find yourself using a pointer ask
yourself if you really need it. In most cases allocating on the stack or
using a reference is just as good.
 
S

Saeed Amrollahi

Hi @ all!

Again one small question due to my shakiness of what to use...

What is better / smarter?

private:
vector<MyClass_t> * itsVector;

OR...

private:
vector<MyClass_t * > * itsVector;

How works such a stl container? Does it use heap or stack?

Thanks

Goran

Hi goran
In addition to the answers by others, I want to say something about
vector<MyClass_t * > itsVector;
sometimes, it depends on your design. For example, if MyClass_t is an
abstract class like Shape in graphics or Piece in Chess, you should
use vector of pointers:
vector<Shape> v; // wrong!
vector<Shape *> v; // ok!
Finally, there should be good reasons for using pointer instead of
plain object.

Regards,
Saeed
 
T

terminator

None of the above, use either

std::vector<MyClass> itsVector;

or

std::vector<MyClass*> itsVector;

Which one you should use depends on how you will use the elements, if
you have not special needs the first one is generally preferable since
it removes the need to new and delete the elements manually.

There might be a few legitimate situations where you might need a
pointer to a vector, but I would say that it is most often a sign of bad
design.


The elements contained in the vector are stored on the heap, notice
thought that for some containers, std::vector among them, the elements
might be re-located when you perform some operations on the containers,
so taking the address of an object can be hazardous.

In fact, I would say that when you find yourself using a pointer ask
yourself if you really need it. In most cases allocating on the stack or
using a reference is just as good.

I tend to consider containers as very huge objects(due to the
unpredictable number of elements),and as far as I have been digging
into my platform`s library neither of STL containers are built upon
the idea of reference counting .I simply conclude that a pointer to a
container is not really that bad.As a rookie I must respect a pro but
I do not see any reason to complaign about 'vector <T> *' as you did.

regards,
FM.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

I tend to consider containers as very huge objects(due to the
unpredictable number of elements),and as far as I have been digging
into my platform`s library neither of STL containers are built upon
the idea of reference counting .I simply conclude that a pointer to a
container is not really that bad.As a rookie I must respect a pro but
I do not see any reason to complaign about 'vector <T> *' as you did.

The actual container is usually quite small, it's the elements contained
that are large. This means that putting a container on the stack and
inserting thousands of objects is no problem, since the objects are on
the heap. The reason I don't recommend using a pointer to a container
(and if possible not a container with pointers) is that it requires the
user to take care of creating and deleting the container (and also the
elements if using a container of pointers).

Imagine a class Foo like this:

class Foo
{
std::vector<Bar> barContainer;
// ...
};

If used like this I don't have to worry about a thing, I know that all
instances will have a barContainer as soon as they are created without
writing anything in the constructor, and when the object is destroyed so
will the container (again, without putting anything in the destructor).
And, when the vector is destroyed so are the elements it contains.

If you had a pointer to the vector you need to new it in the constructor
and delete it in the destructor, or you'll be leaking memory. If you
have a pointer to the vector I'd take that as a sign that the vector is
not owned by the object, perhaps it's shared between many Foo objects or
some such.

If you have a vector of pointers, you must again implement the
destructor, and this time loop through the vector and delete each and
every element in it, or you would be leaking loads of memory.

In short use only pointers where ownership, lifetime, or efficiency
requires it, because it complicates the code.
 
W

werasm

terminator wrote:

I tend to consider containers as very huge objects(due to the
unpredictable number of elements),and as far as I have been digging
into my platform`s library neither of STL containers are built upon
the idea of reference counting.

Then you should have also seen that the contents of containers most
often live on the heap, making there size not much larger than a
pointer.
I simply conclude that a pointer to a
container is not really that bad.

Containers already contain pointers. Apart from the fact that one
needs
to manage a resource that was previously managed automagically,
one also has an additional level of indirection for (in the most
cases)
no reason what-so-ever. This is an example of pre-mature
pessimization.

Regards,

Werner
 
T

terminator

In short use only pointers where ownership, lifetime, or efficiency
requires it, because it complicates the code.

thats exacltly the point,when you need to share a container in
different places, or very simpler the return of a function(this one
mabye bad design).

regards,
FM.
 
T

terminator

Then you should have also seen that the contents of containers most
often live on the heap, making there size not much larger than a
pointer.

I said huge because a container contains data spatered all over the
heap and when it comes to copy(instead of reference) ,then it does not
matter if the data is stored in a contigeous portion of memory or
segmented into peices on different corners of memory.the actual size
of a container is often much larger than its own data structure(one or
two pointers and intrinsic values as well as the vtable in runtime
polymorphic ones).

regards,
FM.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

thats exacltly the point,when you need to share a container in
different places, or very simpler the return of a function(this one
mabye bad design).

If the container is a member of the class using a reference would
probably be better.
 
J

James Kanze

On 2007-09-10 14:16, terminator wrote:

[...]
You can easily use pointers for navigation as well. Vectors or
sets of pointers aren't really that rare, when the vector or set
is only used for navigation, and doesn't imply ownership.
If the container is a member of the class using a reference
would probably be better.

If the class has value semantics, a reference probably isn't a
good idea, since it creates problems for the assignment
operator.
 
W

werasm

terminator wrote:

I said huge because a container contains data spatered all over the
heap and when it comes to copy(instead of reference) ,then it does not
matter if the data is stored in a contigeous portion of memory or
segmented into peices on different corners of memory.the actual size
of a container is often much larger than its own data structure(one or
two pointers and intrinsic values as well as the vtable in runtime
polymorphic ones).

In that case I don't see how it contributes to your argument of using
a pointer to the container instead of the actual container, if I
understand you correctly, as whether one uses a pointer to
a container, or the container itself, you always going to use the
heap, and in the case of a pointer to the container, slightly more
than in the other case, as now the pointer members are also on
the heap.

As far as inside a container is concerned, it depends on the type
T. Typically, if I want to prevent copying, I use either pointers,
or even a pointer_container aka. boost::ptr_vector. If copying of
the container does not happen often, and T has the relevant
members required, then I use T (by value).

Regards,

Werner
 
T

terminator

In that case I don't see how it contributes to your argument of using
a pointer to the container instead of the actual container, if I
understand you correctly, as whether one uses a pointer to
a container, or the container itself, you always going to use the
heap, and in the case of a pointer to the container, slightly more
than in the other case, as now the pointer members are also on
the heap.

only dynamic objects are placed on heap not pointers to objects,also
pointers can simply point to some stack variable in the presenet
thread as well.
The contribution? Very obvious!!! Copying containers is generally both
memory and runtime consuming and should be avoided whenever
possible ,and the simplest way is to use ref/ptr semantics.
As far as inside a container is concerned, it depends on the type
T. Typically, if I want to prevent copying, I use either pointers,
or even a pointer_container aka. boost::ptr_vector. If copying of
the container does not happen often, and T has the relevant
members required, then I use T (by value).

I am talking about the container itself, not the elements.If one
address/refrences a container no element copy is performed but copying
a container is a nightmare sometimes,eventhough elements are pointers.

regards,
FM.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

only dynamic objects are placed on heap not pointers to objects,also
pointers can simply point to some stack variable in the presenet
thread as well.
The contribution? Very obvious!!! Copying containers is generally both
memory and runtime consuming and should be avoided whenever
possible ,and the simplest way is to use ref/ptr semantics.


I am talking about the container itself, not the elements.If one
address/refrences a container no element copy is performed but copying
a container is a nightmare sometimes,eventhough elements are pointers.

Yes, what you say is true, but it is a question of semantics. For some
types the container should be copied for some it should not, you should
only use pointers where the containers are shared (and perhaps not even
then, you can use "smart" containers instead).
 
T

terminator

Yes, what you say is true, but it is a question of semantics. For some
types the container should be copied for some it should not, you should
only use pointers where the containers are shared (and perhaps not even
then, you can use "smart" containers instead).

???what is that one?somewhat smart ptr?

thanks,
FM.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

???what is that one?somewhat smart ptr?

I was thinking about a container (cannot remember which) in Qt3 which
employed copy on write semantics. When you made a copy of the container
all you did was to copy a few variables (a pointer to the data, size,
etc.) and it was first when you tried to make any changes to it that the
elements were copied.

The rationale was that most of the time a container was copied the
elements were only read not modified, so they delayed the actual copy
until modification. To me it sounded like passing by reference might
have solved that one but what do I know.
 
T

terminator

I was thinking about a container (cannot remember which) in Qt3 which
employed copy on write semantics. When you made a copy of the container
all you did was to copy a few variables (a pointer to the data, size,
etc.) and it was first when you tried to make any changes to it that the
elements were copied.

The rationale was that most of the time a container was copied the
elements were only read not modified, so they delayed the actual copy
until modification. To me it sounded like passing by reference might
have solved that one but what do I know.

OK ,reference-counting(marking) with duplication on modification.but
that is still refrencing something which can be an STL container .

thank you again,
FM.
 
W

werasm

terminator said:
only dynamic objects are placed on heap not pointers to objects,

std::vector<int>** ppv = new std::vector<int>*();
*ppv = new std::vector<int>(10,0);

In the case above the pointer was also placed on the heap :).
also pointers can simply point to some stack variable in the present
thread as well.
Of course
The contribution? Very obvious!!! Copying containers is generally both
memory and runtime consuming and should be avoided whenever
possible ,and the simplest way is to use ref/ptr semantics.

In my opinion (and IME) copying is quite a rare occurrence, especially
copying of objects with containers as members. You are compromising
maintainability for efficiency which in most cases give you no gain.

I Agreed that if it did matter, wrap it in a smart pointer (as you
want to
copy, it would probably be a shared pointer). The question remains:
Would you want the copy to be bounded to the original, or not - if
not,
there is no purpose in storing a pointer. I could give you an
elaborate
example, but I hope you understand my point.
I am talking about the container itself, not the elements.If one
address/refrences a container no element copy is performed but copying
a container is a nightmare sometimes,eventhough elements are pointers.

I was talking about both, just incase you were talking about the
other, but
I was especially talking about the container itself.

Regards,

Werner
 
J

James Kanze

terminator wrote:

[...]
In my opinion (and IME) copying is quite a rare occurrence, especially
copying of objects with containers as members.

It depends. Some frequently copied value types could involve
containers: a Position3D class might contain a vector, for
example. Typically, though, you probably won't have to copy
objects with large containers very often, in which case, it
might not affect your runtime that much anyway, and of course,
it's really a question of semantics: if you want or need a copy
of the container, you copy; if identity is important (usually
the case with large containers), you don't.
You are compromising
maintainability for efficiency which in most cases give you no gain.
I Agreed that if it did matter, wrap it in a smart pointer (as
you want to copy, it would probably be a shared pointer). The
question remains: Would you want the copy to be bounded to the
original, or not

Exactly. It's a question of value semantics vs. identity, not
performance. Copying an object and copying a pointer have very
different semantics, and it's hard to imagine a case where you
can replace one with the other. (There are a few exceptions;
e.g. as an out argument of a function. In such cases, *if* the
copy turns out to be a bottleneck, you might have to look for a
different solution---in this specific case, for example, by
having the client declare the container, and pass a non-const
reference to it.)
- if not, there is no purpose in storing a pointer. I could
give you an elaborate example, but I hope you understand my
point.

More generally, dynamic allocation should only be used when
necessary. Off hand, only a few cases come to mind: arbitrary
object lifetime and dynamically sized objects; in some cases,
polymorphic objects may require dynamic allocation as well.
 

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,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top