16

According to C++17 [basic.compound]/3:

Every value of pointer type is one of the following:

  • a pointer to an object or function (the pointer is said to point to the object or function), or
  • a pointer past the end of an object (8.7), or
  • the null pointer value (7.11) for that type, or
  • an invalid pointer value.

The malloc function returns a pointer value. Let us assume the call succeeded, so that the return value is not null. The specification of malloc ([c.malloc]) does not state that it creates any objects in the returned storage, so it seems like "invalid pointer value" is the least nonsensical category.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • 1
    Short answer: [yes.](https://youtu.be/_qzMpk-22cc?t=1400) – Konrad Rudolph Nov 26 '19 at 16:00
  • 3
    Sidenote: The answer would change in future if [p0593rX](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0593r3.html) standard proposal is adopted. – eerorika Nov 26 '19 at 16:04
  • I believe this is type dependent. If you have `int * foo = (int*)malloc(sizeof(int));` then you have a value pointer since an `int`'s lifetime starts when storage is acquired. For something like `std::string` you need to call the constructor so until you do it's invalid. – NathanOliver Nov 26 '19 at 16:11
  • 3
    None of them make sense currently. – T.C. Nov 26 '19 at 19:06
  • @NathanOliver-ReinstateMonica Oh. Hmm. – Lightness Races in Orbit Nov 26 '19 at 19:37
  • @NathanOliver-ReinstateMonica Are you sure? I think it has to be initialised, even if that's merely default-initialisation ([ref](http://eel.is/c++draft/basic.life#1)) - can we say that's happening here? – Lightness Races in Orbit Nov 26 '19 at 19:40
  • Is it an issue, though? Unless you are willing to type-pun, you will have to use placement `new` anyway to get a "meaningful" object, and that doesn't require a valid pointer (only `delete` _does_ require a safely-derived pointer). So I'd say it's all good either way. – Damon Nov 26 '19 at 19:56
  • @lightness default initialization is no initialization for `int` so I believe it still applies. – NathanOliver Nov 26 '19 at 20:02
  • @NathanOliver-ReinstateMonica Hmm not quite convinced. Though default-initialisation means nothing, does nothing mean default-initialisation? – Lightness Races in Orbit Nov 26 '19 at 20:04
  • Yet another proof that the text that tries to specify core C++ is not to be taken literally or seriously. – curiousguy Nov 26 '19 at 21:50
  • 2
    @NathanOliver-ReinstateMonica That code doesn't acquire storage for an `int` object (it acquires storage with no objects) , objects are only created as specified by [intro.object]/1 – M.M Nov 26 '19 at 22:12
  • @m.m of course. That's what I was missing – NathanOliver Nov 26 '19 at 22:25

2 Answers2

8

That makes sense. It's an 'invalid pointer value' because it does not point to an object.

See later in that section, where it says:

A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration

That implies that it's not the "value" of the pointer that makes it invalid, but rather that it does not point to a valid object.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45
  • The text you quote talks about storage, not objects. And it seems at odds with the quotes in the question. What about a pointer that points to an object, and then the object is destroyed but the storage is not released? – M.M Nov 26 '19 at 22:14
  • Then the pointer becomes an "invalid pointer value" – Marshall Clow Dec 17 '19 at 01:52
6

That is correct.

There is no object at that location in memory. The memory "belongs to you". However, whether a pointer is valid is determined not by memory allocations, but by the existence of an object that it points to. This pointer does not point to any object, so it is an invalid pointer.

p0593rX, if adopted in the future, would change this, basically by putting an object there for you. That's actually quite important, because at the moment any use of malloc in C++ I can think of (including placement new) currently has undefined behaviour.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    Actually.... _is_ said placement new valid? Does placement new require a valid pointer input? (Usually it'd be a valid pointer pointing to some `char[]` object) HMM – Lightness Races in Orbit Nov 26 '19 at 16:06
  • It seems that if the pointer value is invalid, then placement new is not guaranteed to work, because in order to call placement new, you need to copy the pointer value into the argument of `::operator new`, which has an implementation-defined result. – Brian Bi Nov 26 '19 at 19:11
  • 1
    @Brian Yep! Hah. So p0593rX isn't just for fun - malloc is _technically_ useless in C++... (which the proposal does almost say tbf) – Lightness Races in Orbit Nov 26 '19 at 19:34