![]() |
Adding pointer to container
Hi, i have a std::vector of pointers to base classes say
std::vector<element*> m_elements; how do i make the followin exception safe function() { element* e= new DerivedElement; m_elements.push_back(element); } the push back operation can throw so i can leak element if it throws i thought of doing this but it still has the same problem as e.get() gets executed first then if the push back throws i leak the pointer. How to solve?? I can't use Boost on this project so the shared_ptr is not an option function() { std::auto_ptr <element> e(new DerivedElement); m_elements.push_back(e.get()); } |
Re: Adding pointer to container
tech wrote:
> Hi, i have a std::vector of pointers to base classes say > std::vector<element*> m_elements; > how do i make the followin exception safe > > function() > { > element* e= new DerivedElement; > m_elements.push_back(element); > } > > the push back operation can throw so i can leak element if it throws > i thought of doing this but it still has the same problem as e.get() > gets executed first > then if the push back throws i leak the pointer. How to solve?? I > can't use > Boost on this project so the shared_ptr is not an option > Then roll your own simple shared_ptr pointer. -- Ian Collins. |
Re: Adding pointer to container
On Jun 11, 12:15*pm, "Chris Thomasson" <cris...@comcast.net> wrote:
> "tech" <naumansulai...@googlemail.com> wrote in message > > news:01e10430-ed77-4643-9e4b-9cd0353a6aba@z66g2000hsc.googlegroups.com... > > > > > > > Hi, i have a std::vector of pointers to base classes *say > > std::vector<element*> m_elements; > > how do i make the followin exception safe > > > function() > > { > > * *element* e= new DerivedElement; > > * *m_elements.push_back(element); > > } > > > the push back operation can throw so i can leak element if it throws > > i thought of doing this but it still has the same problem as e.get() > > gets executed first > > then if the push back throws i leak the pointer. How to solve?? I > > can't use > > Boost on this project so the shared_ptr is not an option > > > function() > > { > > * std::auto_ptr <element> e(new DerivedElement); > > * m_elements.push_back(e.get()); > > } > > You could do something like: > > function() > { > * *std::auto_ptr <element> e(new DerivedElement); > * *m_elements.push_back(e.get()); > * *e.release(); > > > > }- Hide quoted text - > > - Show quoted text -- Hide quoted text - > > - Show quoted text - Replying to Chris Thomasson > std::auto_ptr <element> e(new DerivedElement); > m_elements.push_back(e.get()); > e.release(); But this is what i had above without the e.release() at the bottom, if m_elements.push_back(e.get()); this throws as the e.get() has already given up the pointer then if the push back throws surely i will leak the pointer. Or are you saying the e.get() returns a copy of the pointer and the auto_ptr still hangs onto it. In that case it would work and thanks to you |
Re: Adding pointer to container
Alf P. Steinbach wrote:
> * Paavo Helde: >> >> What about: >> >> void function() >> { >> m_elements.push_back(NULL); >> element*& ref = m_elements.back(); >> ref = new DerivedElement; >> } > > If DerivedElement constructor throws, has already added nullpointer to > vector. > > > Cheers, & hth., > > - Alf > How about using a try/catch. void function() { element * d = new DerivedElement; try { m_elements.push_back(d); } catch (...) { delete d; throw; } } -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/> |
Re: Adding pointer to container
On Wed, 11 Jun 2008 03:36:07 -0700 (PDT), tech rote:
>Hi, i have a std::vector of pointers to base classes say >std::vector<element*> m_elements; >how do i make the followin exception safe > >function() >{ > element* e= new DerivedElement; > m_elements.push_back(element); >} You question includes more than one aspect: 1. STL is designend for values only (a.k.a. 'value semantics'), not objects or pointers to objects. Put simply, STL doesn't work with pointers. 2. You cannot practically 'handle' Out-Of-Memory (OOM). You can do it in theory but it always boils down to terminating the application. Therfore you need not care for OOM conditions or even try to catch std::bad_alloc in your application code. Some OS (e.g. Linux) never indicate OOM. 3. If you still want an 'exception safe' push_back() for vector use reserve() to 'pre-order' enough capacity. Something like the following (BTW, note the difference between reserve() and resize()): if (vec.capacity() == vec.size()) { vec.reserve(vec.capacity() * 2); } vec.push_back(new Element()); -- Roland Pibinger "The best software is simple, elegant, and full of drama" - Grady Booch |
Re: Adding pointer to container
On Sun, 15 Jun 2008 16:30:19 +0200, "Alf P. Steinbach" wrote:
>* Roland Pibinger: >> 2. You cannot practically 'handle' Out-Of-Memory (OOM). > >Well I think I've written something like that in the past. Well, some years ago I thought that you could handle OOM ... >But it's wrong. > >Think about an application where the user attempts to load a very big image >file. If allocation fails, a good way to handle it is to inform the user that >sorry, that file was too big. A bad way to handle it would be to terminate... In case of a file you know the file size in advance and know if the size is within the limits of your function contract. The Java language distinguishes between (recoverable) Exceptions and (fatal) Errors. What can you do after OOM? Can you recover vital memory to proceed? Hardly in practice. IMO, OOM is a fatal error (like stack overflow and memory corruption) that should lead to more or less abrupt termination of the program. This also means that you need not write your code as if std::bad_alloc were a recoverable exception. -- Roland Pibinger "The best software is simple, elegant, and full of drama" - Grady Booch |
Re: Adding pointer to container
Roland Pibinger wrote:
> On Sun, 15 Jun 2008 16:30:19 +0200, "Alf P. Steinbach" wrote: >> * Roland Pibinger: >>> 2. You cannot practically 'handle' Out-Of-Memory (OOM). >> Well I think I've written something like that in the past. > > Well, some years ago I thought that you could handle OOM ... > >> But it's wrong. >> >> Think about an application where the user attempts to load a very big image >> file. If allocation fails, a good way to handle it is to inform the user that >> sorry, that file was too big. A bad way to handle it would be to terminate... > > In case of a file you know the file size in advance and know if the > size is within the limits of your function contract. The Java language > distinguishes between (recoverable) Exceptions and (fatal) Errors. > What can you do after OOM? Can you recover vital memory to proceed? > Hardly in practice. IMO, OOM is a fatal error (like stack overflow and > memory corruption) that should lead to more or less abrupt termination > of the program. This also means that you need not write your code as > if std::bad_alloc were a recoverable exception. > > OOM being fatal depends on the context, in both Java *and* C++. In Java, it is rare, but not unheard-of to recover from an OOM. in C++ it would probably be easier to recover, since you have more control over the deallocation of memory than you do in Java. Like someone said, you can report to the user that the particular operation took too much memory, and to try another operation instead. This is better than, say, crashing an entire photo editing session (probably without saving) because they tried to open one-to-many large photos. Now, if it were a small program used in a form of batch processing, "dieing" on OOM makes more sense, depending on the level of severity of the operation that can't be completed. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/> |
Re: Adding pointer to container
Paavo Helde wrote:
> rpbg123@yahoo.com (Roland Pibinger) kirjutas: > >> On Wed, 11 Jun 2008 03:36:07 -0700 (PDT), tech rote: >>>Hi, i have a std::vector of pointers to base classes say >>>std::vector<element*> m_elements; >>>how do i make the followin exception safe >>> >>>function() >>>{ >>> element* e= new DerivedElement; >>> m_elements.push_back(element); >>>} >> >> You question includes more than one aspect: >> >> 1. STL is designend for values only (a.k.a. 'value semantics'), not >> objects or pointers to objects. Put simply, STL doesn't work with >> pointers. > > It seems this is so ridiculous no one has bothered to answer. For innocent > bystanders I just remind that pointers are values in C++. It is true, though, that pointers often require special handling when dealing with containers. The most basic issue is illustrated by std::map< char const *, some_type > By default, the map will compare pointer values and not the strings they represent. Very likely that is _not_ the desired behavior. Best Kai-Uwe Bux |
Re: Adding pointer to container
Paavo Helde wrote:
> Kai-Uwe Bux <jkherciueh@gmx.net> kirjutas: > >> Paavo Helde wrote: >> >>> rpbg123@yahoo.com (Roland Pibinger) kirjutas: >>> >>>> On Wed, 11 Jun 2008 03:36:07 -0700 (PDT), tech rote: >>>>>Hi, i have a std::vector of pointers to base classes say >>>>>std::vector<element*> m_elements; >>>>>how do i make the followin exception safe >>>>> >>>>>function() >>>>>{ >>>>> element* e= new DerivedElement; >>>>> m_elements.push_back(element); >>>>>} >>>> >>>> You question includes more than one aspect: >>>> >>>> 1. STL is designend for values only (a.k.a. 'value semantics'), not >>>> objects or pointers to objects. Put simply, STL doesn't work with >>>> pointers. >>> >>> It seems this is so ridiculous no one has bothered to answer. For >>> innocent bystanders I just remind that pointers are values in C++. >> >> It is true, though, that pointers often require special handling when >> dealing with containers. The most basic issue is illustrated by >> >> std::map< char const *, some_type > >> >> By default, the map will compare pointer values and not the strings >> they represent. Very likely that is _not_ the desired behavior. > > If you specify the map keys as pointers, they will be compared as > pointers, that's it. Actually, nobody knows how they are compared. [20.3.3/8] just requires std::less<T*> to yield a total order. There is no requirement whatsoever that this order is related to or compatible with pointer comparison as per [5.9/2]. > I see nothing specific to STL here. Huh? How is the default behavior of STL containers not specific to STL? > You could easily instruct the map to use the string comparison (if/when > needed) instead by providing an extra template argument for the map > declaration. Of course, one _can_ do that. Often, one even _must_ do that. And sometimes, people are not aware of the issue (which addresses your claim that it is "easy": nothing is easy to do when you don't know that you should), which is why related bugs come up in postings to this group where the standard answer is: use std::string or provide a forwarding comparison predicate. > IOW, STL does what it is told to do. It does not attempt to read your > mind. This is a Good Thing IMO. I did not give an evaluation of any sort. I just felt the need to point out that there are technical issues when using pointers in STL containers. I did not suggest changing the STL nor did I claim that other alternatives are preferable. To me, it's just a matter of awareness. Best Kai-Uwe Bux |
Re: Adding pointer to container
"Chris Thomasson" <cristom@comcast.net> writes:
>In C, if malloc returns NULL, what do you do? In C, you usually want to make sure not to dereference this result and you do not need to call free for it. For example, assume that a calculation needed a temporary buffer of 1024 char objects. This buffer might be obtained from the stack, but just to show how a 0 result from malloc would be handled, I request the buffer from the heap. /** Does some calculation. @param x the argument for the calculation @param y where to store the result in case of success @returns 0 to indicate success, otherwise an error has happened, and y does not refer to a valid result */ int calculate( double const x, double * const y ) { char * buffer; if( buffer = malloc( 1024 )) { int const status = do_calculate( x, y, buffer ); free( buffer ); return status; } else return 1; } |
| All times are GMT. The time now is 07:42 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.