new-expression and delete-expression on const reference and const pointer
Asked Answered
C

2

0

C++

Much literature says const references cannot be used to modify their referents and const pointers cannot be used to modify their pointees.

Then, why can they be deleted?

const int& cirDynamic = *( new int(5) );
// ^ 'const int& cirDynamic = *( &( *( new int(5) ) ) );' gives same output below
cout << cirDynamic << endl; // 5
delete &cirDynamic;
cout << cirDynamic << endl; // garbage value

I know the trailing const in T* const only prevents the pointer from being reseated, but below I use two consts, as in const T* const, for emphasis. Why can the following pointer be deleted?

const int* const cipcDynamic =  new int(5);
// ^ 'const int* const cipcDynamic = &( *( new int(5) ) );' gives same output below
cout << *cipcDynamic << endl; // 5
delete cipcDynamic;
cout << *cipcDynamic << endl; // garbage value

The output shows that at least some dynamically allocated memory was freed. Has all of it been freed, or could there have been copying involved where only the copy was freed?

The non-const version of the const reference snippet (int&) and the non-leading-const versions of the const pointer const snippet (int* const and int*) produce the same output as their more const counterparts. In all 5 cases, why and how is the lifetime of the temporary new-expression extended?

Assuming the corresponding operator has not been overloaded, explicitly deleted, or made non-public if the data type is a class or struct, does the Standard make the following guarantees:

  • The dereference operator provides direct access to the pointee

  • The new operator produces a pointer to the dynamically allocated memory, not a dynamically allocated copy of the original dynamically allocated memory

If instead the new operator was overloaded but still returned ::operator new(size) and the dereference operator was overloaded but still returned a reference to the object, are there any side-effects that would make these two points not hold?

Commandeer answered 11/10, 2013 at 21:48 Comment(3)
Which aspect of this needs explaining?Batfowl
Yeah, you're gonna need to be a little more specific. Are you asking why you first see a 5 displayed, and then see a garbage value?Deferral
@KerrekSB @NateKohl : Edited it, questioning why delete can be used if pointer and reference are const.Commandeer
B
2

Constness affects objects themselves. new and delete and constructors affect the creation of objects. It doesn't make sense to ask whether constructors or destructors are const, because they run before or after the object exists. Similarly, you can create and destroy constant objects dynamically, and/or you can manage dynamically created objects through constant pointers or references.

As a very simple thought experiment, consider this code:

{
    const int x = 0;
}

This wouldn't work if constness could prevent the object x from being destroyed.

Batfowl answered 11/10, 2013 at 22:23 Comment(0)
S
2

'const' in all your examples only prevents you to modify the variable through assignment. That's all it does. It does not prevent delete to reclaim the memory.

In your first example, "const int& cirDynamic" prevents you to write something like "cirDynamic=2". But it's legal to take address of cirDynamic (which will get you a "const int*" pointer), and delete would operate on const pointers happily.

In your second example, "const int* const cipcDynamic", the first const prevents you from modifying the place pointed by the pointer, like "*cipcDynamic = 2", the second const prevents you from modifying the pointer itself to point to another place, like "cipcDynamic = new int".

Schizo answered 11/10, 2013 at 22:16 Comment(0)
B
2

Constness affects objects themselves. new and delete and constructors affect the creation of objects. It doesn't make sense to ask whether constructors or destructors are const, because they run before or after the object exists. Similarly, you can create and destroy constant objects dynamically, and/or you can manage dynamically created objects through constant pointers or references.

As a very simple thought experiment, consider this code:

{
    const int x = 0;
}

This wouldn't work if constness could prevent the object x from being destroyed.

Batfowl answered 11/10, 2013 at 22:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.