Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > how to delete vectors that contain pointers to user-defined type objects

Reply
Thread Tools

how to delete vectors that contain pointers to user-defined type objects

 
 
dwightarmyofchampions@hotmail.com
Guest
Posts: n/a
 
      06-16-2012
On Saturday, June 16, 2012 1:36:30 PM UTC-4, (unknown) wrote:
> On Saturday, June 16, 2012 6:56:05 PM UTC+2, (unknown) wrote:
> > This must be pointer because it's a VCL class, so it must be declared using new on the heap.
> >
> > It is also an old compiler so I can't use fancy new pointers like shared_ptr or auto_ptr.

>
> I don't remember what was available in VCL at what point, nor do you specify the compiler version, but I would be surprised to hear that auto_ptr is not available in it, as auto_ptr is pretty old.
>


Specifically, it is C++ Builder in Borland Developer Studio 2006. I don't think you can use boost or auto_ptrs with that, but I might be wrong.
 
Reply With Quote
 
 
 
 
Jorgen Grahn
Guest
Posts: n/a
 
      06-16-2012
On Sat, 2012-06-16, wrote:
> This must be pointer because it's a VCL class, so it must be declared using new on the heap.


"Visual Component Library", some Delphi thing. I had to look it up.

> It is also an old compiler so I can't use fancy new pointers like shared_ptr or auto_ptr.


Uh, hasn't auto_ptr been standard for 15 years or so? (Not that it
helps here since AFAIK it doesn't mix well with containers.)

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
 
 
 
Jorgen Grahn
Guest
Posts: n/a
 
      06-16-2012
On Sat, 2012-06-16, Tobias Müller wrote:
> Jorgen Grahn <grahn+> wrote:
>> On Fri, 2012-06-15, Tobias Müller wrote:
>>> Juha Nieminen <> wrote:
>>>> wrote:
>>>>> unique_ptr<Movie> p(new Movie(...));
>>>>> movies.push_back(p.get());
>>>>> p.release();
>>>>>
>>>>> Movie* p = new Movie(...);
>>>>> try { movies.push_back(p); }
>>>>> catch(...)
>>>>> {
>>>>> delete p;
>>>>> throw;
>>>>> }
>>>>>
>>>>> std::vector< std::shared_ptr<Movie> >;
>>>>
>>>> What is wrong with just std::vector<Movie>?
>>>
>>> It is probably just a an example of a Problem that happened in a larger
>>> context.
>>> 1. When Movie is a large object (e.g. contains the cover image) and has no
>>> move constructor, copying is expensive.
>>> 2. There may other objects containing pointers to that movies. This is at
>>> least problematic. You have to be sure, that the objects are never copied.
>>> 3. If there are subclasses of Movie you have to use pointers.

>>
>> Yes -- except the OP's very basic questions makes one wonder if one of
>> those was his reason, or if the vector<T*> design happened by accident
>> or misunderstanding.
>>
>> /Jorgen

>
> Even if that's the case, it leads him to the wrong direction.


No, the default strategy for everyone should be not to mess with
pointers, plain or smart. It's things like 1--3 above which may force
you to do it.

> A std::vector<std::shared_ptr<Movie>> almost equally safe with respect to
> memory leaks.
> The problems you can run into with a std::vector<Movie> however can be much
> more subtle and difficult to even notice them. Consider an insert or a
> push_front into the vector. In the most cases all pointers to the existing
> objects are still valid but now pointing to different objects.


But everyone has to learn to handle that anyway! Unless they /never/
store objects by value in containers, and that would look rather
unusual.

(Of course, this being comp.lang.c++, someone will now claim
containers of pointers is the only way to do it, and be very
insistent.)

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
goran.pusic@gmail.com
Guest
Posts: n/a
 
      06-17-2012
On Saturday, June 16, 2012 10:13:22 PM UTC+2, (unknown) wrote:
> On Saturday, June 16, 2012 1:36:30 PM UTC-4, (unknown) wrote:
> > On Saturday, June 16, 2012 6:56:05 PM UTC+2, (unknown) wrote:
> > > This must be pointer because it's a VCL class, so it must be declaredusing new on the heap.
> > >
> > > It is also an old compiler so I can't use fancy new pointers like shared_ptr or auto_ptr.

> >
> > I don't remember what was available in VCL at what point, nor do you specify the compiler version, but I would be surprised to hear that auto_ptr is not available in it, as auto_ptr is pretty old.
> >

>
> Specifically, it is C++ Builder in Borland Developer Studio 2006. I don'tthink you can use boost or auto_ptrs with that, but I might be wrong.


You can most certainly do what I have shown you about setting an Owner for your TComponent. In fact, if you want your code to be exception-safe, that's exactly what you need to do - that's idiomatic C++, VCL or not. Alternatively, you should use the try/catch from my first post. Naive code, e.g.

TWhateverComponent* p = new TWhateverComponent(...)
p->Owner = someOtherTComponent;

is not exception-safe.

I don't quite understand why you think that you can't use boost or standardC++ lib with VCL. They don't mix (how could they? VCL is written in another language altogether), that is true, but they won't cause each other to stop working either.

Goran.

P.S. I speak of TComponent::Owner and TComponent::Components only because this is an out-of-the box way to create ownership trees in VCL and thereforeshould work in your case. In no way are you required to do it.
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      06-18-2012
Jorgen Grahn <grahn+> wrote:
> (Of course, this being comp.lang.c++, someone will now claim
> containers of pointers is the only way to do it, and be very
> insistent.)


Storing pointers to individually allocated objects is necessary in some
situations (mainly those where you need runtime polymorphism) but in
practice this is quite rarely the case. You probably need to do so more
often in certain types of applications or libraries (a GUI library being
a good example), but even then it's relatively rare.

Someone raised the concern that copying large objects inside a vector can
be expensive. If that's a real concern, then std::deque is the solution to
that. (It's not like std::vector is the only available data container.)
IMO better to use std::deque than going the complicated route of starting
to allocate individual objects and handling pointers to them. That's only
going to end in trouble.
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      07-09-2012
On Jun 15, 2:51*pm, dwightarmyofchampi...@hotmail.com wrote:
> 1. When we push_back a new Movie*, we are copying by value, so the new Movie parameter immediately goes out of scope. Is that a memory leak, and if so how do I fix it?


You copy the pointer by value; so you have two pointers to the same
memory (temoprarily). Then one pointer goes out of scope (but the
thing it's pointed to is still alive), no problem.

> 2. To delete the ten elements in movies, do I leave the iterator for loopwhere it is or do I put it in the Libraries destructor, or do both?


Well, if it's in both then you get a segfault because you called
'delete' twice on the same pointer. My answer would be 'neither'
though, see below

> 3. Are movies and this->video_library pointing to the same memory? I guess that would be so, since that's what the line in the constructor is doing,pointing them both to the same address in memory. If so, how do I be sure that I'm deleting the elements being pointed to only once? If I change the Libraries destructor to the following:


That line in the constructor is creating a second vector
that's an exact copy of the first. You now have two vectors
each containing 10 pointers (and the pointers in one
point to the same memory as the pointers in the other).

This is OK per se, but you have to think carefully about how
is responsible for deleting the pointers.

Of course, boost::shared_ptr is one option; another is using
the VCL ownership mechanism, as other posters have suggested.

If you didn't like either of those, what you could do is put
all your "new"'d stuff into a container, which you then
"delete" at the end. For example:

vector<Movie *> all_movies;
Movie *temp = new Movie(....);
all_movies.push_back(temp);
movies.push_back(temp);

and then manipulate your movies with impunity, but don't tough
"all_movies". Then at the end of your program delete everything
in all_movies.

This setup doesn't work so well if you want to delete
movies before the end of the program; shared_ptr is
designed exactly for that.
 
Reply With Quote
 
nick_keighley_nospam@hotmail.com
Guest
Posts: n/a
 
      07-09-2012
On Saturday, June 16, 2012 10:10:50 PM UTC+1, Jorgen Grahn wrote:
> On Sat, 2012-06-16, Tobias Müller wrote:
> > Jorgen Grahn <grahn+> wrote:
> >> On Fri, 2012-06-15, Tobias Müller wrote:
> >>> Juha Nieminen <> wrote:


<snip>

> >>>> What is wrong with just std::vector<Movie>?


[rather than using some sort of pointer]

<snip>

[reasons to use containers of pointers]

> >>> 1. When Movie is a large object (e.g. contains the cover image) and has no
> >>> move constructor, copying is expensive.
> >>> 2. There may other objects containing pointers to that movies. This is at
> >>> least problematic. You have to be sure, that the objects are never copied.
> >>> 3. If there are subclasses of Movie you have to use pointers.
> >>
> >> Yes -- except the OP's very basic questions makes one wonder if one of
> >> those was his reason, or if the vector<T*> design happened by accident
> >> or misunderstanding.

> >
> > Even if that's the case, it leads him to the wrong direction.

>
> No, the default strategy for everyone should be not to mess with
> pointers, plain or smart. It's things like 1--3 above which may force
> you to do it.
>
> > A std::vector<std::shared_ptr<Movie>> almost equally safe with respect to
> > memory leaks.
> > The problems you can run into with a std::vector<Movie> however can be much
> > more subtle and difficult to even notice them. Consider an insert or a
> > push_front into the vector. In the most cases all pointers to the existing
> > objects are still valid but now pointing to different objects.

>
> But everyone has to learn to handle that anyway! Unless they /never/
> store objects by value in containers, and that would look rather
> unusual.


this is one of the reasons I prefer pointers...

> (Of course, this being comp.lang.c++, someone will now claim
> containers of pointers is the only way to do it, and be very
> insistent.)




well, I'm not going to be very insistant, but. Maybe it's my C/embedded back-ground but as soon as the object becomes non-trivial in size then I automatically think "pointers" (I grew up when memory were very small and copying *anything* was expensive). Plus the polymorphism thing. Am I unusual, that containers of polymorphic objects are very common in my designs?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
RCR: String#contain? and Array#contain? Roger Pack Ruby 3 09-28-2010 04:13 PM
Does string contain A, and if so, does a section of string contain B Jason Carlton Javascript 11 12-08-2009 06:07 PM
Deleting elements of vectors that contain pointers to other objects dwightarmyofchampions@hotmail.com C++ 7 03-20-2009 09:06 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57