473,382 Members | 1,743 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

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 <elemente(new DerivedElement);
m_elements.push_back(e.get());
}
Jun 27 '08 #1
18 2178
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.
Jun 27 '08 #2
"tech" <na************@googlemail.comwrote in message
news:01**********************************@z66g2000 hsc.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 <elemente(new DerivedElement);
m_elements.push_back(e.get());
}
You could do something like:

function()
{
std::auto_ptr <elemente(new DerivedElement);
m_elements.push_back(e.get());
e.release();
}
Jun 27 '08 #3
On Jun 11, 12:15*pm, "Chris Thomasson" <cris...@comcast.netwrote:
"tech" <naumansulai...@googlemail.comwrote in message

news:01**********************************@z66g2000 hsc.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 <elemente(new DerivedElement);
* m_elements.push_back(e.get());
}

You could do something like:

function()
{
* *std::auto_ptr <elemente(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 <elemente(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
Jun 27 '08 #4
tech <na************@googlemail.comkirjutas:
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
What about:

void function()
{
m_elements.push_back(NULL);
element*& ref = m_elements.back();
ref = new DerivedElement;
}

HTH
Paavo
Jun 27 '08 #5
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/>
Jun 27 '08 #6
"Alf P. Steinbach" <al***@start.nokirjutas:
* 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.
Yes, that's true. What I would do actually in this case, would be to use
the ScopeGuard from Andrei Alexandrescu. This is a case of glueing
together C-style interfaces (raw pointers!) and ScopeGuard comes quite
handy in such situations:

#include <ScopeGuard/ScopeGuard.h>

template <class T>
struct Delete {
void operator()(T *t) const { delete t;}
};
void function()
{
element* e = new DerivedElement;
ScopeGuard guard = MakeGuard(Delete<element>(), e);
m_elements.push_back(e);
guard.Dismiss();
}

But this is only because I have the Delete template and ScopeGuard
includes already in place in the project anyway. std::auto_ptr would work
the same in this case (I suppose, never used myself) and would require
less code in this case.

Regards
Paavo
Jun 27 '08 #7
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
Jun 27 '08 #8
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/>
Jun 27 '08 #9
rp*****@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++.

Paavo
Jun 27 '08 #10
Paavo Helde wrote:
rp*****@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
Jun 27 '08 #11
Kai-Uwe Bux <jk********@gmx.netkirjutas:
Paavo Helde wrote:
>rp*****@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. I see nothing specific to STL here.

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.

IOW, STL does what it is told to do. It does not attempt to read your
mind. This is a Good Thing IMO.

Regards
Paavo
Jun 27 '08 #12

"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:48***************@news.utanet.at...
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.
http://groups.google.com/group/comp....20a821b10a3c72

In C, if malloc returns NULL, what do you do? Well, you could try something
like:

http://groups.google.com/group/comp....7956d31e6ca5cc

OOM is _not_ "always" a _fatal_ error. You can certainly attempt a
recovery...

Jun 27 '08 #13
On Sun, 15 Jun 2008 17:31:38 -0700, "Chris Thomasson" wrote:
>In C, if malloc returns NULL, what do you do? Well, you could try something
like:

http://groups.google.com/group/comp....7956d31e6ca5cc
I agree with you: "we are screwed!!! :^o".

--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Jun 27 '08 #14
On Jun 15, 11:02*am, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Sun, 15 Jun 2008 16:30:19 +0200, "Alf P. Steinbach" wrote:
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 program could well determine that the file's size does fall within
the limits of its "contract" - but nonetheless have its attempt to
allocate enough memory to open the file - fail. Moreover, one could
imagine that a reasonable contract for a file-opening routine would be
to open the requested file - but to do so only if enough memory is
available. So not every attempted memory allocation has to succeed -
for a program to operate correctly.
The Java language
distinguishes between (recoverable) Exceptions and (fatal) Errors.
What can you do after OOM? Can you recover vital memory to proceed?
There may be no need for the program to recover any memory. After all,
an out-of-memory error does not necessarily mean that the program is
close to exhausting its available memory. In fact, the app has just as
much free memory available ater the failed allocation as it had
beforehand. The only sure conclusion that one draw from an out-of-
memory is: that the amount of memory requested - was too large.
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.
Stack overflows and memory corruption represent irretrievable loss of
data - data needed for the program to operate correctly. A memory
allocation failure does not represent a similar loss of data; so there
is no reason why a memory allocation failure should necessarily be a
fatal error. On the contrary, for certain types of programs
(particular those that are document-oriented), a well-written program
will anticipate that certain, discretionary memory allocations will
fail - and will therefore handle that possibility, correctly.

Greg

Jun 27 '08 #15
On 16 Jun, 09:28, Paavo Helde <nob...@ebi.eewrote:
Kai-Uwe Bux <jkherci...@gmx.netkirjutas:
Paavo Helde wrote:
Kai-Uwe Bux <jkherci...@gmx.netkirjutas:
Paavo Helde wrote:
rpbg...@yahoo.com (Roland Pibinger) kirjutas:
On Wed, 11 Jun 2008 03:36:07 -0700 (PDT), tech rote:
>>>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.
really? This is kind of scary to learn...

>>It seems this is so ridiculous no one has bothered to answer. For
innocent bystanders I just remind that pointers are values in C++.
<snip>
[...] this does not justify the claim posted by Mr.
Bibinger: "Put simply, STL doesn't work with pointers.". For example, in
case of polymorphic objects a vector of raw pointers is a quite
reasonable thing to have, especially if the lifetime of the objects is
maintained elsewhere (by GC, for example).
ah good. I was beginning to worry... A vector of pointers to
polymorphic
objects seems like a *very* resonable thing to have!

<snip>
--
Nick Keighley
Jun 27 '08 #16
On Jun 16, 2:45 pm, Greg Herlihy <gre...@mac.comwrote:
On Jun 15, 11:02 am, rpbg...@yahoo.com (Roland Pibinger) wrote:
[...]
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.
Stack overflows and memory corruption represent irretrievable
loss of data - data needed for the program to operate
correctly.
That's true for memory corruption, but not for stack overflow.
Stack growth is memory allocation; the only real difference
between it and operator new failing is that C++ doesn't provide
any formal means of managing it. Under most Unix, or at least,
under Solaris, there are means if you know what you're doing,
and I've written server applications which were guaranteed not
to crash because of stack overflow---they would respond with an
"insufficient resources" error, just as they would if new
failed.

In practice, for some types of servers, crashing because you
couldn't allocate memory is just not allowed. (For a lot of
others, of course, it *is* what you want to do. It all depends
on the application.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #17
"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:48***************@news.utanet.at...
On Sun, 15 Jun 2008 17:31:38 -0700, "Chris Thomasson" wrote:
>>In C, if malloc returns NULL, what do you do? Well, you could try
something
like:

http://groups.google.com/group/comp....7956d31e6ca5cc

I agree with you: "we are screwed!!! :^o".
;^)

Jun 27 '08 #18
Paavo Helde wrote:
tech <na************@googlemail.comkirjutas:
>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

What about:

void function()
{
m_elements.push_back(NULL);
element*& ref = m_elements.back();
ref = new DerivedElement;
}

HTH
Paavo
I don't usually handle most OOM problems but what I do in code is use
auto_ptr a bit. Maybe something like this will work:

std::auto_ptr<elemente(new DerivedElement);
m_elements.push_back(e.get());
e.release();

Brian Vanderburg II
Jun 27 '08 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

34
by: Adam Hartshorne | last post by:
Hi All, I have the following problem, and I would be extremely grateful if somebody would be kind enough to suggest an efficient solution to it. I create an instance of a Class A, and...
1
by: Janiek Buysrogge | last post by:
Hello, I've written a Windows Forms application in .NET 2.0 and am exposing it to COM using the checkbox in Project Properties and by adding some register functions and adding it to the GAC. I'm...
18
by: silversurfer | last post by:
Ok, this should be fairly easy for most of you (at least I hope so), but not for me: Let us say we have got the following elements: std::vector<Entry> models; //Entry is a struct...
9
by: axel22 | last post by:
Hello, I have the following problem. I create a class called MyClass which includes another class calles MyContainer. Class MyContainer has a member which is a vector, instantiated as...
19
by: Michael | last post by:
Hi, typedef std::vector<Vehicle* VehicleList; Vehicle is a UDT, or a class. Why is Vehicle* not just Vehicle in < >. Which one is better and why? If you could explain it by laying out some...
11
by: toton | last post by:
Hi, all of the containers in STL stores object itself (thus copy contsructability & assignability is needed), while NTL or boost ptr_container stores pointer to the object in the container (either...
30
by: Jess | last post by:
Hello, I tried a program as follows: include<iostream> using namespace std; class A{ public:
3
by: Rob McDonald | last post by:
I am interested in having a container which has properties of both the STL's list and vector. (I want my cake and to eat it too). In my application, I will need to add/remove items from arbitrary...
8
by: mathieu | last post by:
Hi there I have implemented a very simple smartpointer class (invasive design). And I was wondering what should be the natural API when using those in a Container. I choose to define the...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.