473,404 Members | 2,114 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,404 software developers and data experts.

Is this valid and moral C++?

Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,

filimon
Mar 18 '07 #1
30 1872
Filimon Roukoutakis wrote:
Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,
Yes, it is valid.

Objects allocated by new are available to any function before delete is
called on it.
Mar 18 '07 #2
On Sun, 18 Mar 2007 21:09:22 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}
No. The function should receive the pointer argument by value. i.e.
f(Object* obj)

It is invalid to try to pass a modifiable reference to the result of
..back() , and while a const reference would work it has no particular
advantage.

Secondly, your global vector of Object* will NOT delete the objects
pointed to when it's destructor runs at the end of the program. There's
no big deal about reclaiming the memory at that point, but if Object's
destructor does anything else important you've got a problem.
>ie does f() internally actually have read/write access to the Object
allocated in g() on the heap?
Yes. In fact that is the only way of accessing the object that you have
left yourself at this point, which is fine.

Mar 18 '07 #3
David Harmon wrote:
On Sun, 18 Mar 2007 21:09:22 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

No. The function should receive the pointer argument by value. i.e.
f(Object* obj)

It is invalid to try to pass a modifiable reference to the result of
.back() , and while a const reference would work it has no particular
advantage.

Why is it "invalid" ?
Mar 18 '07 #4
David Harmon wrote:
On Sun, 18 Mar 2007 21:09:22 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

No. The function should receive the pointer argument by value. i.e.
f(Object* obj)

It is invalid to try to pass a modifiable reference to the result of
.back() , and while a const reference would work it has no particular
advantage.
I do want to pass a reference to the pointer so the pointer is
modifiable, or more precicely I want to use this pointer in another
context in the program while it is by itself updated by f. Could you
comment on the invalidity of modifiable reference?
>
Secondly, your global vector of Object* will NOT delete the objects
pointed to when it's destructor runs at the end of the program. There's
no big deal about reclaiming the memory at that point, but if Object's
destructor does anything else important you've got a problem.
>ie does f() internally actually have read/write access to the Object
allocated in g() on the heap?

Yes. In fact that is the only way of accessing the object that you have
left yourself at this point, which is fine.
ok for the above I knew, it was just a minimal example.

filimon
Mar 18 '07 #5
David Harmon wrote:
On Sun, 18 Mar 2007 21:09:22 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

No. The function should receive the pointer argument by value. i.e.
f(Object* obj)
Why?
It is invalid to try to pass a modifiable reference to the result of
.back() , and while a const reference would work it has no particular
advantage.
The call f(vec.back()) does not pass anything "to the result of .back()".
What it does is: it initializes the Object*& parameter of f() with the
result of vec.back(), which so happens to be a reference (non-const in case
the non-const version of back() is called). There is nothing invalid about
it, as far as I can see.

E.g., f() could be:

f ( Object* & p_ref ) {
Object * dummy = new Object ();
std::swap( p_ref, dummy );
delete dummy;
}

Then f(vec.back()) would replace the last pointer with a new pointer whose
pointee has been default constructed.

Secondly, your global vector of Object* will NOT delete the objects
pointed to when it's destructor runs at the end of the program. There's
no big deal about reclaiming the memory at that point, but if Object's
destructor does anything else important you've got a problem.
Right: the vector will not do that by itself. So, the OP will have to take
care of deleting the pointers by himself.
[snip]

Mar 18 '07 #6
On Sun, 18 Mar 2007 22:37:29 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>I do want to pass a reference to the pointer so the pointer is
modifiable, or more precicely I want to use this pointer in another
context in the program while it is by itself updated by f. Could you
comment on the invalidity of modifiable reference?
What does it mean when your code attempts to modify via the reference,
giving in effect:
vec.back() = (some expression);

As I wrote to Gianni, It is forbidden by the standard to bind a
non-const reference to a temporary. This is one case where that rule
probably even makes sense. If you could actually change the value of
vec.back() without resizing the vector, it would break the vector. If
you think you can resize the vector by, for instance, incrementing
vec.back(), it doesn't work that way.

Mar 18 '07 #7
On Mon, 19 Mar 2007 08:30:34 +1100 in comp.lang.c++, Gianni Mariani
<gi*******@mariani.wswrote,
>It is invalid to try to pass a modifiable reference to the result of
.back() , and while a const reference would work it has no particular
advantage.


Why is it "invalid" ?
It is forbidden by the standard to bind a non-const reference to a
temporary. This is one case where that rule probably even makes sense.
If you could actually change the value of vec.back() without resizing
the vector, it would break the vector. If you think you can resize the
vector by, for instance, incrementing vec.back(), it doesn't work that
way.

Mar 18 '07 #8
On Sun, 18 Mar 2007 18:13:46 -0400 in comp.lang.c++, Kai-Uwe Bux
<jk********@gmx.netwrote,
>The call f(vec.back()) does not pass anything "to the result of .back()".
What it does is: it initializes the Object*& parameter of f() with the
result of vec.back(), which so happens to be a reference (non-const in case
the non-const version of back() is called). There is nothing invalid about
it, as far as I can see.
Doh! I was confusing the element access front() and back() with the
iterator functions begin() etc. Disregard all.
Mar 18 '07 #9
On Mon, 19 Mar 2007 08:30:34 +1100 in comp.lang.c++, Gianni Mariani
<gi*******@mariani.wswrote,
>It is invalid to try to pass a modifiable reference to the result of
.back() , and while a const reference would work it has no particular
advantage.


Why is it "invalid" ?

Doh! I was confusing the element access front() and back() with the
iterator functions begin() etc. Disregard all.
Mar 18 '07 #10
On Sun, 18 Mar 2007 22:37:29 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>context in the program while it is by itself updated by f. Could you
comment on the invalidity of modifiable reference?
Doh! I was confusing the element access front() and back() with the
iterator functions begin() etc. Disregard all.

Mar 18 '07 #11
"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:et**********@cernne03.cern.ch...
Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,
By your replies to the other posts, I take it you meant

void g() {
vec push_back( new Object );
f( vec[size() - 1] );
}

f( *(vec.end() - 1) );
may also work.

Your question seems to be, g made a new object, can f access that object?
The answer is yes. It would be the same if you did something like:

Object* MyObject = NULL;

f( Object*& obj )
{
// ...
}

Object* g
{
return new Object;
}

int main()
{
MyObject = g();
f( MyObject );
delete( MyObject );
}

You just happen to be storing it in a vector instead of (in thsi case) a
global variable. Once an object is allocated using new all you need is the
pointer to that memory to access the instance, until delete is called on it.
However you happen to get that pointer (global, from a vecotr, a paramter,
whatever).

Incidently, now a days "heap" is commonly called the "free store". I'm not
sure what the standard calls it.

Just make sure you delete the pointer when done.
Mar 18 '07 #12
Jim Langston wrote:
"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:et**********@cernne03.cern.ch...
>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,

By your replies to the other posts, I take it you meant

void g() {
vec push_back( new Object );
f( vec[size() - 1] );
}

f( *(vec.end() - 1) );
may also work.

Your question seems to be, g made a new object, can f access that object?
The answer is yes. It would be the same if you did something like:

Object* MyObject = NULL;

f( Object*& obj )
{
// ...
}

Object* g
{
return new Object;
}

int main()
{
MyObject = g();
f( MyObject );
delete( MyObject );
}

You just happen to be storing it in a vector instead of (in thsi case) a
global variable. Once an object is allocated using new all you need is the
pointer to that memory to access the instance, until delete is called on it.
However you happen to get that pointer (global, from a vecotr, a paramter,
whatever).

Incidently, now a days "heap" is commonly called the "free store". I'm not
sure what the standard calls it.

Just make sure you delete the pointer when done.

My problem is that when I try to delete the pointer inside f I get a
segmentation violation, so I figured that maybe new Object inside g is
stored as a const reference in the vector which cannot be modified
somehow and this produces the problem.
Mar 19 '07 #13
On Mon, 19 Mar 2007 10:28:48 +0100 in comp.lang.c++, Filimon Roukoutakis
<fi*****@phys.uoa.grwrote,
>
My problem is that when I try to delete the pointer inside f I get a
segmentation violation, so I figured that maybe new Object inside g is
stored as a const reference in the vector which cannot be modified
somehow and this produces the problem.
No. The contents of the vector, in this case the pointers, are fully
modifiable just as you thought. Even if that were not the case, const
pointers can be deleted as long as they came from 'new' to begin with.
I apologize for muddying the waters.

seg violation on deleting usually means either you are trying to delete
the same object twice, or some pointer that was never new'ed, or that
some random memory write elsewhere in the program has corrupted the
heap. Or something along those lines. Can be tricky to track down.

Mar 20 '07 #14
"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:et**********@cernne03.cern.ch...
: Suppose that we have a function
:
: f(Object*& obj)
:
: and have declared a global std::vector<Object*vec;
:
: Is it valid to do
:
: void g() {
: vec.push_back(new Object);
: f(vec.back());
: }
:
: ie does f() internally actually have read/write access to the Object
: allocated in g() on the heap? If not, what would be the trick to
achieve
: this? Thanks,

That part is ok. The only problem I see in the above code is
something that hasn't been mentioned yet:
vec.push_back(new Object);
This is not exception-safe: if push_back fails (because it
is unable to allocate a larger block of memory), the newly
allocated object will be leaked.

But this of course will be unrelated to the problem
you described later.
For that, be careful that you do not modify the vector
(e.g. by adding another element) as long as you are
using the reference returned by back().

hth -Ivan

--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Mar 20 '07 #15
On Tue, 20 Mar 2007 07:27:17 +0100, "Ivan Vecerina" wrote:
>The only problem I see in the above code is
something that hasn't been mentioned yet:
vec.push_back(new Object);
This is not exception-safe: if push_back fails (because it
is unable to allocate a larger block of memory), the newly
allocated object will be leaked.
Out-of-memory in C++ is usually handled by the new_handler, not with
exception handling. If one really needs to handle OOM with exception
handling vector::reserve() may be called in advance.

Best regards,
Roland Pibinger
Mar 20 '07 #16
"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:45**************@news.utanet.at...
: On Tue, 20 Mar 2007 07:27:17 +0100, "Ivan Vecerina" wrote:
: >The only problem I see in the above code is
: >something that hasn't been mentioned yet:
: vec.push_back(new Object);
: >This is not exception-safe: if push_back fails (because it
: >is unable to allocate a larger block of memory), the newly
: >allocated object will be leaked.
:
: Out-of-memory in C++ is usually handled by the new_handler, not with
: exception handling.

What is your definition of "usually" ???
http://www.google.com/codesearch?q=set_new_handler
This gives 2-3'000 hits, many of them being declarations
in library headers. Not quite was I would call "usual".
Plus new_handler is required to either throw an exception,
or terminate the program. Does it really help here ?

: If one really needs to handle OOM with exception
: handling vector::reserve() may be called in advance.

Yes, this is one of several ways to address the problem.
All I am saying is that this issue is worth attention.

Regards,
Ivan

--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com

Mar 22 '07 #17
Filimon Roukoutakis wrote:
Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,

filimon
Problem solved. The problem was that the above code produced a
segmentation violation in another part of the program. The fix was to
replace std::vector<Object*with std::vector<Object**and
vec.push_back(new Object*). Probably this was not obvious in the context
of the code snippet that was presented here. Thanks for the answers.

filimon
Mar 23 '07 #18
"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:eu**********@cernne03.cern.ch...
Filimon Roukoutakis wrote:
>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,

filimon

Problem solved. The problem was that the above code produced a
segmentation violation in another part of the program. The fix was to
replace std::vector<Object*with std::vector<Object**and
vec.push_back(new Object*). Probably this was not obvious in the context
of the code snippet that was presented here. Thanks for the answers.
std::vector<someclass*is usually bad design unless you are working with
polymorphism. Even then some would say use a smart pointer (although I use
naked pointers myself).

std::vector<someclass**I could only think is bad design. You may want to
relook at what you are doing and see if this is absolutly necessary, it
sounds like a maintainance nightmare.
Mar 24 '07 #19
Filimon Roukoutakis wrote:
:: Filimon Roukoutakis wrote:
::: Suppose that we have a function
:::
::: f(Object*& obj)
:::
::: and have declared a global std::vector<Object*vec;
:::
::: Is it valid to do
:::
::: void g() {
::: vec.push_back(new Object);
::: f(vec.back());
::: }
:::
::: ie does f() internally actually have read/write access to the Object
::: allocated in g() on the heap? If not, what would be the trick to
::: achieve this? Thanks,
:::
::: filimon
::
:: Problem solved. The problem was that the above code produced a
:: segmentation violation in another part of the program. The fix was to
:: replace std::vector<Object*with std::vector<Object**and
:: vec.push_back(new Object*).

Agreeing with Jim Langston's post, I can only say that dynamically
allocating a single pointer is EXTREMELY unusual.

In my opinion, it is HIGHLY LIKELY that you have not actually solved the
problem, but only happen to hide it.
Bo Persson
Mar 24 '07 #20

Ivan Vecerina wrote:
Yes, this is one of several ways to address the problem.
All I am saying is that this issue is worth attention.
Yes, I cannot understand Roland's point too. Obviously reserve might
solve the problem. I think it could cause unnecessary memory
allocation though. I would prefer:

std::auto_ptr<Objectinstance( new Object );
myVector.push_back( instance.get() ); //X
instance.release(); //No X

Werner

Mar 24 '07 #21
werasm wrote:
>
Ivan Vecerina wrote:
>Yes, this is one of several ways to address the problem.
All I am saying is that this issue is worth attention.

Yes, I cannot understand Roland's point too. Obviously reserve might
solve the problem. I think it could cause unnecessary memory
allocation though. I would prefer:

std::auto_ptr<Objectinstance( new Object );
myVector.push_back( instance.get() ); //X
instance.release(); //No X
Alternatively,

myVector.push_back( 0 );
myVector.back() = new Object;

looks exception safe, too.
Best

Kai-Uwe Bux
Mar 24 '07 #22
On 24 Mar 2007 08:04:48 -0700, "werasm" wrote:
>Yes, this is one of several ways to address the problem.
All I am saying is that this issue is worth attention.
Yes, I cannot understand Roland's point too. Obviously reserve might
solve the problem. I think it could cause unnecessary memory
allocation though.
OOM can be handled by a global new_handler if the operating system
supports it. Linux e.g. uses 'optimistic memory allocation' so
checking for OOM exceptions is not useful there. See also Moral #2
here: http://www.gotw.ca/publications/mill16.htm
>I would prefer:

std::auto_ptr<Objectinstance( new Object );
myVector.push_back( instance.get() ); //X
instance.release(); //No X
This is impractical for any real-world program. In general you need
not check within your program for OOM, stack overflow, int overflow,
etc.. You can reasonably assume that you are in 'secure territory'.

Best wishes,
Roland Pibinger


Mar 24 '07 #23
"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:46**************@news.utanet.at...
: On 24 Mar 2007 08:04:48 -0700, "werasm" wrote:
: >Yes, this is one of several ways to address the problem.
: >All I am saying is that this issue is worth attention.
: >>
: >Yes, I cannot understand Roland's point too. Obviously reserve might
: >solve the problem. I think it could cause unnecessary memory
: >allocation though.
:
: OOM can be handled by a global new_handler if the operating system
: supports it. Linux e.g. uses 'optimistic memory allocation' so
: checking for OOM exceptions is not useful there. See also Moral #2
: here: http://www.gotw.ca/publications/mill16.htm

I rarely check for new/memory allocations in my code. I only do my
best to write code that is exception-safe. New-ing an object can
fail in any case because of a constructor failure.
Given, push_back of a pointer is unlikely to fail, yet formally
it is a container operation that is allowed to fail and throw
an exception. So I'll write my code "to the spec".

: >I would prefer:
: >
: >std::auto_ptr<Objectinstance( new Object );
: >myVector.push_back( instance.get() ); //X
: >instance.release(); //No X
:
: This is impractical for any real-world program.

Indeed. The real issue is that it is illegal to create a
container of auto_ptr. vector<T*is brittle by nature.

When I have a container of polymorphic objects, I find
that the overhead of vector< shared_ptr<T is acceptable.
When not using polymorphic objects, I do not use containers
of pointers, but a container of <T- with possibly some
accessory "index" containers storing pointers that refer
into an "allocation" container (a list or deque).

In C++0x, with the introduction of R-value references, I expect
that an equivalent of vector< auto_ptr<T will become available
in the standard library.

: In general you need
: not check within your program for OOM, stack overflow, int overflow,
: etc.. You can reasonably assume that you are in 'secure territory'

I write software for medical devices.

You think that one can just assume that int overflows never happen?

void on_decrement_radiation_power()
{
--ray_power; // safe? what if unsigned ray_power was zero?
}

Depending on the type of device your code runs on, you will also
ensure that stack overflows can't be triggered by excessive
recursion, or ensure graceful failure if sufficient memory
isn't available for new incoming data.
Cheers -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Mar 25 '07 #24

Ivan Vecerina wrote:
: >I would prefer:
: >
: >std::auto_ptr<Objectinstance( new Object );
: >myVector.push_back( instance.get() ); //X
: >instance.release(); //No X
:
Indeed. The real issue is that it is illegal to create a
container of auto_ptr. vector<T*is brittle by nature.
Yes, but you of course realise that the container was not a container
of auto_ptr's. Notice the <get()in the call to push_back. The
container only contained normal pointers, hence the call to release
afterwards.

That said, I have read the article Roland mentioned. For me it is
actually concerning that the possibility exists that a call to
something like buffer_[x] = 'y' might fail with a much worse exception
than bad_alloc (like an access violation). Even when one does get to
the situation where memory becomes a problem (and this is certainly a
possibility, especially when writing application where resources are
constraining - embedded linux), one would like to have the means of
taking action.

For instance, take your medical applications for example:

In the event of memory failure, one would possible want to disable a
less critical portion of the program, freeing its memory and allowing
for a more critical portion to try again - especially when a life
depends on the execution of a more critical part.

I suppose for these kinds of programs one will have to revert to pre-
allocated memory period (possible overloading new/deletes to only us
this). How do you even know whether the pre-allocated memory was
really allocated?

Although memory failure is very rare, if it is a possibility at all,
one would like it to fail deterministically.

Regards,

Werner

Mar 25 '07 #25
On Sun, 25 Mar 2007 10:48:07 +0200, "Ivan Vecerina" wrote:
>I rarely check for new/memory allocations in my code. I only do my
best to write code that is exception-safe. New-ing an object can
fail in any case because of a constructor failure.
Yes, constructor failure is something you expect. It's entirely
different from OOM, stack overflow, ...
>Given, push_back of a pointer is unlikely to fail, yet formally
it is a container operation that is allowed to fail and throw
an exception. So I'll write my code "to the spec".
Allowed, but not required. So maybe the spec is defective?
>The real issue is that it is illegal to create a
container of auto_ptr. vector<T*is brittle by nature.
When I have a container of polymorphic objects, I find
that the overhead of vector< shared_ptr<T is acceptable.
I don't think that 'smart pointes' solve any problem (BTW, a container
for auto_ptrs is not difficult but why should one use it? See:
http://www.relisoft.com/resource/auto_vector.html).
>Depending on the type of device your code runs on, you will also
ensure that stack overflows can't be triggered by excessive
recursion, or ensure graceful failure if sufficient memory
isn't available for new incoming data.
IMO, the question is which resources you can rely on withing your
program and which not. Checking for stack overflow, OOM, ... would
severely impair the creation of reusable components. You must rely on
some solid ground for your programming.

Best wishes,
Roland Pibinger
Mar 25 '07 #26
"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:46*************@news.utanet.at...
: On Sun, 25 Mar 2007 10:48:07 +0200, "Ivan Vecerina" wrote:
: >I rarely check for new/memory allocations in my code. I only do my
: >best to write code that is exception-safe. New-ing an object can
: >fail in any case because of a constructor failure.
:
: Yes, constructor failure is something you expect. It's entirely
: different from OOM, stack overflow, ...

As I previously pointed out, what you expect is dependent on
the platform and application that you are working on.

: >Given, push_back of a pointer is unlikely to fail, yet formally
: >it is a container operation that is allowed to fail and throw
: >an exception. So I'll write my code "to the spec".
:
: Allowed, but not required. So maybe the spec is defective?

You mean, maybe the experience of the designers of the C++
language and libraries pales in comparison to yours?
You mean, it should not be possible to write an allocator
that can fail to allocate memory on a platform with limited
resources, and throw an exception to allow graceful recovery?

: >The real issue is that it is illegal to create a
: >container of auto_ptr. vector<T*is brittle by nature.
: >When I have a container of polymorphic objects, I find
: >that the overhead of vector< shared_ptr<T is acceptable.
:
: I don't think that 'smart pointes' solve any problem

Smart pointers (seek to) address the problem of memory leaks.
In your opinion, so many people have been working on smart
pointers for no reason ?

: (BTW, a container
: for auto_ptrs is not difficult but why should one use it?
: See: http://www.relisoft.com/resource/auto_vector.html).

The difficulty of implementing a solution is proportional
to the breadth of its applicability.
Have you considered, for example, that:
- you'd have to rewrite a whole separate container
to have an auto_list
- it is unsafe to use auto_vector::iterator with
many standard algorithms, such as std::unique

I would suggest reading this introduction to R-value references
http://www.open-std.org/jtc1/sc22/wg...2002/n1377.htm
[ here's a convenient index into more info about R-value
references and other C++ features that are in development:
http://www.open-std.org/jtc1/sc22/wg...007/n2169.html ]

: >Depending on the type of device your code runs on, you will also
: >ensure that stack overflows can't be triggered by excessive
: >recursion, or ensure graceful failure if sufficient memory
: >isn't available for new incoming data.
:
: IMO, the question is which resources you can rely on withing your
: program and which not.
This is simple: what can be relied on or not, for portable C++ code,
is defined in the C++ standard. And according to this specification,
vector::push_back is allowed to throw an exception.

: Checking for stack overflow, OOM, ... would
: severely impair the creation of reusable components.

I have never suggested checking for stack overflow. But if I write
a recursive algorithms I will make sure, for example, that its
worst case recursion depth is logarithmic to the size of its input.
I do not specifically check for out-of-memory exceptions, but I use
RAII-related idioms to write code that is (hopefully) exception-safe
and immune to resource leaks.

: You must rely on some solid ground for your programming.

Isn't this exactly what I am doing by not making
platform-specific assumptions?
Take care -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Mar 26 '07 #27
Hi, Werner,
"werasm" <we****@gmail.comwrote in message
news:11**********************@d57g2000hsg.googlegr oups.com...
:
: Ivan Vecerina wrote:
:
: : >I would prefer:
: : >
: : >std::auto_ptr<Objectinstance( new Object );
: : >myVector.push_back( instance.get() ); //X
: : >instance.release(); //No X
: :
: Indeed. The real issue is that it is illegal to create a
: container of auto_ptr. vector<T*is brittle by nature.
:
: Yes, but you of course realise that the container was not a container
: of auto_ptr's. Notice the <get()in the call to push_back. The
: container only contained normal pointers, hence the call to release
: afterwards.

My comment was not about the correctness of the solution
you posted (no question about this). I was only regretting
that it required 3 lines of code instead of one.

: That said, I have read the article Roland mentioned. For me it is
: actually concerning that the possibility exists that a call to
: something like buffer_[x] = 'y' might fail with a much worse exception
: than bad_alloc (like an access violation). Even when one does get to
: the situation where memory becomes a problem (and this is certainly a
: possibility, especially when writing application where resources are
: constraining - embedded linux), one would like to have the means of
: taking action.

This implementation approach ("lazy commit") might be a reasonable
choice for destop systems - assuming that the user is alerted when
swap memory nears exhaustion, and that the user will first notice
system thrashing and look into releasing memory.
I am not a linux expert, but on many platforms it is possible to
specify the maximum memory that can be allocated to a process,
and I wouldn't be surprised if this were the case in Linux as well.
Critical applications and servers may use their own allocators,
and impose hard limits on their total resource allocations
(or use other hard limits, such as the maximum number of sessions
that a server may open simultaneously).
Tuning these hard limits is part of the job of a competent
server system administrator...

: For instance, take your medical applications for example:
:
: In the event of memory failure, one would possible want to disable a
: less critical portion of the program, freeing its memory and allowing
: for a more critical portion to try again - especially when a life
: depends on the execution of a more critical part.

Small embedded critical systems simply avoid making any memory
allocations at all.
As aplications and devices become more complex, the emphasis
is not as much on avoiding any failure (difficult to prove) as
on making sure that failure is handled gracefully.
On an X-ray machine, an external watchdog will immediately stop
all irradiation if the software stops responding, or if a certain
output threshold is reached). In your car a shut-down of the
ABS electronics will not prevent (mechanically-transmitted)
breaking force from functioning (unless you have one of these
specific models that attempted break-by-wire).

: Although memory failure is very rare, if it is a possibility at all,
: one would like it to fail deterministically.
Yes.

Kind regards,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Mar 26 '07 #28
Jim Langston wrote:
"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:eu**********@cernne03.cern.ch...
>Filimon Roukoutakis wrote:
>>Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to achieve
this? Thanks,

filimon
Problem solved. The problem was that the above code produced a
segmentation violation in another part of the program. The fix was to
replace std::vector<Object*with std::vector<Object**and
vec.push_back(new Object*). Probably this was not obvious in the context
of the code snippet that was presented here. Thanks for the answers.

std::vector<someclass*is usually bad design unless you are working with
polymorphism. Even then some would say use a smart pointer (although I use
naked pointers myself).
I am working with polymorphism. At some point I was reading strong
statements about not using std::smart_ptr with std::containers. Did I
misunderstand?
>
std::vector<someclass**I could only think is bad design. You may want to
relook at what you are doing and see if this is absolutly necessary, it
sounds like a maintainance nightmare.

Mar 26 '07 #29
"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:eu**********@cernne03.cern.ch...
Jim Langston wrote:
>"Filimon Roukoutakis" <fi*****@phys.uoa.grwrote in message
news:eu**********@cernne03.cern.ch...
>>Filimon Roukoutakis wrote:
Suppose that we have a function

f(Object*& obj)

and have declared a global std::vector<Object*vec;

Is it valid to do

void g() {
vec.push_back(new Object);
f(vec.back());
}

ie does f() internally actually have read/write access to the Object
allocated in g() on the heap? If not, what would be the trick to
achieve this? Thanks,

filimon
Problem solved. The problem was that the above code produced a
segmentation violation in another part of the program. The fix was to
replace std::vector<Object*with std::vector<Object**and
vec.push_back(new Object*). Probably this was not obvious in the context
of the code snippet that was presented here. Thanks for the answers.

std::vector<someclass*is usually bad design unless you are working with
polymorphism. Even then some would say use a smart pointer (although I
use naked pointers myself).

I am working with polymorphism. At some point I was reading strong
statements about not using std::smart_ptr with std::containers. Did I
misunderstand?
Probably not. There are a few people who don't like smart pointers for
various reasons.

The question becomes, then, why do you need a someclass** instead of a
class*? Unless you are changing where the pointer is pointing somewhere, in
which case wouldn't it just be better to overwrite the value?
Mar 26 '07 #30
In message <eu**********@cernne03.cern.ch>, Filimon Roukoutakis
<fi*****@phys.uoa.grwrites
>Jim Langston wrote:
[...]
> std::vector<someclass*is usually bad design unless you are working
with polymorphism. Even then some would say use a smart pointer
(although I use naked pointers myself).

I am working with polymorphism. At some point I was reading strong
statements about not using std::smart_ptr with std::containers. Did I
misunderstand?
There's no such animal as std::smart_ptr, so the question is what kind
of pointer they really meant. Probably they meant that you can't have
std::containers of std::auto_ptr, because it doesn't model normal copy
semantics.

--
Richard Herring
Apr 3 '07 #31

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

Similar topics

12
by: lawrence | last post by:
I have a string which I want to send to eval(). How can I test it ahead of time to make sure it is valid code? I don't want to send it to eval and get parse errors. I want to do something like...
16
by: siliconmike | last post by:
Hi, I'm looking for a reliable script that would connect to a host and somehow determine whether an email address is valid. since getmxrr() only gets the mx records.. Links/pointers ? Mike
1
by: Anna | last post by:
Hi all. I have probably a rather stupid question. If there is an HTML document, XML-formed using JTidy, is there any tool to convert it to valid XHTML? I.e. so that all the tags and attribute...
7
by: JR | last post by:
Hey all, I have read part seven of the FAQ and searched for an answer but can not seem to find one. I am trying to do the all too common verify the data type with CIN. The code from the FAQ...
23
by: James Aguilar | last post by:
Someone showed me something today that I didn't understand. This doesn't seem like it should be valid C++. Specifically, I don't understand how the commas are accepted after the function...
0
by: QA | last post by:
I am using a Business Scorecard Accelarator in a Sharepoint Portal 2003 using SQL Server 2005 I am getting the following error: Error,5/7/2005 10:50:14 AM,580,AUE1\Administrator,"Specified cast is...
10
by: SpreadTooThin | last post by:
Hi I'm writing a python script that creates directories from user input. Sometimes the user inputs characters that aren't valid characters for a file or directory name. Here are the characters...
18
by: John Salmon | last post by:
I was under the impression that the following was always valid: std::vector<Tv; .. T *p = &(v); But I was recently told that care was needed in case the vector was empty, i.e., when v.size()...
4
by: George2 | last post by:
Hello everyone, In GotW #66, one of the moral is the exception handler of constructor should not do any like resource free task. I do not agree. Here is the quoated moral and my code to prove...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...

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.