3

In this Informit C++ guide, I read this:

Using malloc() to create a non–POD object causes undefined behavior:

//disastrous!
std::string *pstr =(std::string*)malloc(sizeof(std::string));

I didn't understand 2 points here :

  • Pointers are PODs. Then why it is called non-POD here? (Maybe I have to understand POD better.)
  • How can this be so disastrous? (I guess I have to understand string Internals for this.)

Please explain!

Community
  • 1
  • 1
Swathi Appari
  • 193
  • 1
  • 1
  • 12
  • 1
    You are not "creating a pointer" in this case. You are "creating" a `std::string` object. `std::string` is not POD. – AnT stands with Russia Jul 07 '12 at 07:06
  • 1
    The answer is in the link your mentioned: "new and delete automatically construct and destroy objects. malloc() and free(), on the other hand, merely allocate and deallocate raw memory from the heap." – laurent Jul 07 '12 at 07:22
  • If you add to that `malloc()` an in-place constructor invocation (look up `new()` for that), it'll be OK. But then you'll need to call the destructor manually and `free()` the memory, not `delete` it. – Alexey Frunze Jul 07 '12 at 07:26

2 Answers2

5

pointers are PODs then why here it is called non-POD

It's not talking about the pointer, but the std::string.

It's disastruous because malloc doesn't call the constructor, so you'll have pstr a std::string pointer that points to a std::string that wasn't properly constructed. The memory was allocated but it wasn't initialized properly, because of the missing constructor call.

The correct way is

std::string *pstr = new std::string;

The clean way is to just have a variable in automatic storage:

std::string str;
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

Here you are allocating a standard string, not allocating a pointer to a standard string. Note that you are passing sizeof(std::string) to malloc; that is how much memory you are getting back...note the size of the object is bigger than the size of a pointer. If you were only allocating a pointer, you'd expect the size passed in to be sizeof(std::string*).

The pointer you receive back is how you keep track of the result of the allocation, but that pointer isn't living on the heap. Here it's just being stored in an ordinary variable. Had you allocated a pointer instead, then your variable to keep track of it would need to be a pointer-to-a-pointer.

Anyway, if you wanted to, you could legally allocate a pointer to a standard string like this:

std::string str;
std::string** ptr_to_pstr = (std::string**)malloc(sizeof(std::string*);
*ptr_to_pstr = &str;

Why you would want to is not entirely clear. But neither is it clear why you'd use malloc in C++. :)