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.

6
  • Related “constructing” a trivially-copyable object with memcpy Commented Feb 7, 2018 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. Commented Feb 7, 2018 at 19:44
  • Maybe duplicate At what point does memory allocated by malloc get a type? Commented Feb 7, 2018 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. Commented Feb 7, 2018 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. Commented Feb 7, 2018 at 20:14

1 Answer 1

-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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.