References and destruction

  • Thread starter Ulrich Hobelmann
  • Start date
U

Ulrich Hobelmann

Assuming I have an object containing a reference to something (which is
passed along with the object's constructor), does the automatic default
destructor take care of destroying the reference's object, or do I have
to write my own explicit destructor? If not, does the default
destructor work for pointers (assuming they're non-NULL)?
 
F

Frederick Gotham

Ulrich Hobelmann posted:
Assuming I have an object containing a reference to something (which is
passed along with the object's constructor), does the automatic default
destructor take care of destroying the reference's object
No.

or do I have
to write my own explicit destructor?


Yes.

#include <new>

class Arb {
public:

int *p;

int &r;


Arb() : p( new(std::nothrow) int[64] ),
r( *new(std::nothrow) int[64] ) {}

~Arb()
{
/* Both of these delete's are necessary: */

delete [] p;

delete [] &r;
}
};
 
U

Ulrich Hobelmann

Frederick said:
~Arb()
{
/* Both of these delete's are necessary: */

delete [] p;

delete [] &r;
}
};

Hm, does it work with non-arrays too?

When I try to delete my reference, the compiler says "class argument
given to delete; expected pointer".

If it really doesn't work for references, I'll have to go with pointers,
after all (even though refs are much nicer, and my pointers are const
and non-null anyway)...
 
F

Frederick Gotham

Ulrich Hobelmann posted:
Frederick said:
~Arb()
{
/* Both of these delete's are necessary: */

delete [] p;

delete [] &r;
}
};

Hm, does it work with non-arrays too?


"p" is a pointer variable. It stores an address. The address stored
within it is the address of the first element of a dynamically allocated
array.

"r" is a reference. It refers to the first element of a dynamically
allocated array.

The operator, "delete []", seeks as an operand the address of the first
element of a dynamically allocated array. Therefore:

delete [] p;

delete [] &r; /* Note the address-of operator */
 
T

Thomas J. Gritzan

Frederick said:
#include <new>

Why do you said:
class Arb {
public:

int *p;

int &r;


Arb() : p( new(std::nothrow) int[64] ),
r( *new(std::nothrow) int[64] ) {}

A reference "pointing" to a non-object? Doesn't the standard guarantee,
that a reference is always bound to an object?
~Arb()
{
/* Both of these delete's are necessary: */

delete [] p;

delete [] &r;
}
};

Thomas
 
F

Frederick Gotham

Thomas J. Gritzan posted:
Why do you, for a "minimal" example, use include <new> and use
std::nothrow?


Q. Why did I include <new>?
A. To use a feature declared in that header.

Q. Why did I use nothrow?
A. So that a dynamic allocation failure wouldn't result in an exception
being thrown.

A reference "pointing" to a non-object?


Before you question my code, may I suggest that you know what you're
talking about?

The operator "new []" evaluates to a pointer to the first element of the
dynamically allocated array. Dereference that pointer and you have the
first element of the array. There is no "non-object" to speak of.

Stare at this for twenty minutes until it sinks in:

#include <iostream>

int main()
{
int i = 0;

int *p = &i;

int &r = *p;

r = 666;

std::cout << i << '\n';
}

Doesn't the standard guarantee, that a reference is always bound to an
object?


The Standard stipulates that a reference must refer to a valid object;
thus the following code is broken:

int main()
{
int *p = 0;

int &r = *p; /* Forbidden */
}


As is the following:


int main()
{
int array[8];

int *p = array + 8; /* No problem */

int &r = *p; /* Forbidden */
}
 
T

Thomas J. Gritzan

Frederick said:
Q. Why did I use nothrow?
A. So that a dynamic allocation failure wouldn't result in an exception
being thrown.

Instead, it returns a null-pointer.
Before you question my code, may I suggest that you know what you're
talking about?

I do.
The operator "new []" evaluates to a pointer to the first element of the
dynamically allocated array. Dereference that pointer and you have the
first element of the array. There is no "non-object" to speak of.

Not my point.

[snip]
The Standard stipulates that a reference must refer to a valid object;
thus the following code is broken:

int main()
{
int *p = 0;

int &r = *p; /* Forbidden */
}

Exactly.

Q1: What does new when an allocation failure happens?
Q2: What does new(std::nothrow) in this case?
Q3: What happens, if you do

int &r = new(std::nothrow) int;

in case of an allocation failure?

Thomas
 
T

Thomas J. Gritzan

Thomas said:
Q1: What does new when an allocation failure happens?
Q2: What does new(std::nothrow) in this case?
Q3: What happens, if you do

int &r = new(std::nothrow) int;

Should be:

int &r = *new(std::nothrow) int;
 
M

Murali Krishna

Hi,
I see all heated arguments over here. Don't know why? Is this an
information exchange group or is this meant for throwing stones on one
another?

-- Murali Krishna
 
H

Howard

Frederick Gotham said:
Ulrich Hobelmann posted:


No.

True, but that's because you don't WANT to destroy a reference. It refers
to an object whose lifetime is managed elsewhere.

That's not true (except in your example, where you use new to create a new
object for the reference to refer to).

A reference does not need to be destroyed, and there is no direct mechanism
for doing so. And even if you could, that would usually result in multiple
destruction of an object. A reference refers to an existing object, and the
lifetime of that object is usually managed elsewhere. So destroying the
object via its reference would leave whatever was managing the lifetime of
the object in an invalid state.

The example given just happens to be using a reference member to point to
some memory which is newed and must therefore be deleted somewhere (and the
only thing refering to that memory happens to be a reference variable).
It's a contrived example, and isn't really germaine to the question.

Do references need to be deleted? The answer is no.

-Howard
 
F

Frederick Gotham

Howard posted:

Do references need to be deleted? The answer is no.


I gathered from the original post in the thread that the OP was referring
to references which refer to dynamically allocated objects.
 
H

Howard

Frederick Gotham said:
Howard posted:




I gathered from the original post in the thread that the OP was referring
to references which refer to dynamically allocated objects.

Understood. But in most cases, such objects are dynamically allocated and
assigned to a pointer somewhere, and it is that pointer which needs to have
delete called on it, not any reference variables which may later refer to
it. Just wanted the OP to understand that.

-Howard
 
U

Ulrich Hobelmann

Howard said:
True, but that's because you don't WANT to destroy a reference. It refers
to an object whose lifetime is managed elsewhere.

Oh, that's the purpose? Hmm, well I'm building a recursive data
structure. Does that mean my only option is pointers? (maybe I've
gotten the wrong impression, that pointers aren't much used anymore in
C++, and are mostly a C legacy)
A reference does not need to be destroyed, and there is no direct mechanism
for doing so. And even if you could, that would usually result in multiple

Well, I pass in a newly created object which needs to be destroyed when
the containing object is. It's basically like a tree.
 
U

Ulrich Hobelmann

Howard said:
Understood. But in most cases, such objects are dynamically allocated and
assigned to a pointer somewhere, and it is that pointer which needs to have
delete called on it, not any reference variables which may later refer to
it. Just wanted the OP to understand that.

Oh sure, understood :)
 
H

Howard

Ulrich Hobelmann said:
Oh, that's the purpose? Hmm, well I'm building a recursive data
structure. Does that mean my only option is pointers?

I can't tell without seeing your code, or at least something describing the
structure in question.

References may be fine. Pointers may be fine. It all depends on details we
don't see here.
(maybe I've gotten the wrong impression, that pointers aren't much used
anymore in C++, and are mostly a C legacy)

Pointers are used quite often in C++. It's often preferable to avoid them
(in favor of automatic objects) if you don't need them, but it's also true
that you often need them! :)
Well, I pass in a newly created object which needs to be destroyed when
the containing object is. It's basically like a tree.

Since you didn't post any code, I can't tell exactly what you mean. It
_may_ be that what you want is a pointer member, not a reference member. No
way to tell without seeing your code.

But if you _do_ use pointers, you need to be sure that each
dynamically-allocated object is destroyed exactly once.

-Howard
 
U

Ulrich Hobelmann

Howard said:
I can't tell without seeing your code, or at least something describing the
structure in question.

References may be fine. Pointers may be fine. It all depends on details we
don't see here.

As I said, base class + several subclasses. All references are mostly
to the base class, so I have to use pointers or refs, no direct objects,
as the size varies.

It's mostly a tree, with the constructor being called with the node's
child nodes (of the base class)...

new SubNodeA(new SubNodeB(), bla) and stuff like that.
Pointers are used quite often in C++. It's often preferable to avoid them
(in favor of automatic objects) if you don't need them, but it's also true
that you often need them! :)

Ok, then I'm fine.
Since you didn't post any code, I can't tell exactly what you mean. It
_may_ be that what you want is a pointer member, not a reference member. No
way to tell without seeing your code.

I used pointers in the C version, but I thought refs might be nicer in
C++, because that implies they're immutable and non-NULL (which they are).
But if you _do_ use pointers, you need to be sure that each
dynamically-allocated object is destroyed exactly once.

Yep, it's a tree, so no problems there. References to external objects
can use refcounting; everything is cycle-free.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Ulrich said:
Oh, that's the purpose? Hmm, well I'm building a recursive data
structure. Does that mean my only option is pointers? (maybe I've
gotten the wrong impression, that pointers aren't much used anymore in
C++, and are mostly a C legacy)

The thing being destroyed is not a pointer, is an object. The pointer just
points, as is his habitual work, to the object you want to destroy. If you
maintains a reference to the dynamically created object instead of a
pointer to it, you can provide a pointer just by using &, there is no need
to add another syntax or semantic to use delete with references.
 
D

Diego Martins

int &r = *new(std::nothrow) int;

you will be judged by commiting a fatal sin

exceptions is the only way to avoid dangling references. this is one of
most imprudent code snippets i've ever seen
 

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,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top