1

Does this code have undefined behavior in C++?

#include <cstdlib>

int main() {
    int *ip = static_cast<int *>(std::malloc(sizeof *ip));
    *ip = 42; //is this accessing an object that has not started its lifetime?
    free(ip);
}

Notes:
std::malloc has the semantics that it has in C. In C std::malloc creates valid ints, so it should be valid?

The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. [ Note: Initialization by a trivial copy/move constructor is non-vacuous initialization. — end note  ] The lifetime of an object of type T begins when:

(1.1) storage with the proper alignment and size for type T is obtained, and
(1.2) if the object has non-vacuous initialization, its initialization is complete,

except that if the object is a union member or subobject thereof ...

source

I'm fairly sure this quote answers my question but I don't understand it well enough to tell if it is saying yes or no.

nwp
  • 9,623
  • 5
  • 38
  • 68
  • Related [“constructing” a trivially-copyable object with memcpy](https://stackoverflow.com/q/30114397/1708801) – Shafik Yaghmour Feb 07 '18 at 19:44
  • That quote is not relevant, and this has been discussed what feels like 1 million times. Hang on, I'll look for a dupe. – Baum mit Augen Feb 07 '18 at 19:44
  • Maybe duplicate [At what point does memory allocated by malloc get a type?](https://stackoverflow.com/q/36024325/1708801) – Shafik Yaghmour Feb 07 '18 at 19:45
  • 1
    Don't use `malloc`/`free` in C++. Use `new`/`delete`. Or better yet; don't. Use RAII, automatic objects, containers and smart pointers and avoid manual memory management. – Jesper Juhl Feb 07 '18 at 19:56
  • I assume there's a good reason the standard committee changed "non-trivial initialization" to "non-vacuous initialization", but I sure don't like the new term. I thought that "vacuous" on that link might have come from some computer-based language translation or something, but I see it's in C++17. – Michael Burr Feb 07 '18 at 20:14
  • @MichaelBurr: It's getting around the fact that a "trivial" copy or move constructor does a bitwise image of a valid object. "vacuous" in contrast means *nothing* is done. – Ben Voigt Feb 07 '18 at 21:42

1 Answers1

-2

Your object has type int, which doesn't require non-trivial initialization, so both bullet points are satisfied just by calling std::malloc.

If the object requires a non-trivial constructor call, then new is the way to satisfy (1.2) and if you want to use an allocator other than operator new() then placement new is the right approach.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720