Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no realloc equivalent to the new/delete family?

As the title says, I know there is no equivalent to C's realloc in the new/delete family of operators.

I have already found this question that lightly touches on the subject but it doesn't really answer the "why".

My questions are:

  1. Why is it a bad idea to be able to realloc objects?
  2. Why is it a bad idea for an object to change its size? (Implementing a collection seems a perfectly valid reason for an object to change its size.)
  3. What rule would be broken in these cases and why is this rule objectively good?
like image 800
Rares Dima Avatar asked Jul 01 '21 13:07

Rares Dima


People also ask

Can you use realloc with new?

You can, but it might not turn out well. I don't think malloc/realloc/free are supposed to be mixed with new/delete. If you want to realloc some memory allocated with new, you should do some kind of allocate-copy-free pattern. as suggested, using a vector is the simplest solution.

Does C++ have realloc?

C++ realloc() The realloc() function in C++ reallocates a block of memory that was previously allocated but not yet freed. The realloc() function reallocates memory that was previously allocated using malloc(), calloc() or realloc() function and yet not freed using the free() function.

Does realloc keep old memory?

No, the data will be copied for you into the new block that the returned p points at, before the old block is freed.

Is realloc 0 same as free?

C Language Memory management realloc(ptr, 0) is not equivalent to free(ptr)


Video Answer


2 Answers

Realloc has two behaviors, one of them is not acceptable in the C++ object model. Realloc can increase the size of a piece of storage, or it can allocate new storage and copy everything from the old storage into the new.

The thing is, C++ doesn't think of objects as just bags of bits. They're living, breathing types that hold invariants. And some of those invariants don't tolerate having their bits copied around well.

In C++, copying an object's bits does not mean you have effectively copied the object. This is only allowed for trivially copyable types, and there are plenty of types that aren't trivially copyable.

As such, a C++ realloc equivalent cannot be used on any allocation. You would need to split the call into two separate calls: one that attempts to expand the memory and does nothing if it can't, and the regular heap allocation call into which you would manually copy using existing C++ techniques.


As one example, many std::list implementations store a terminator node in the std::list object itself which is used to represent the start/end of the linked list. If you simply copied its bits, pointers to the terminator node would point to the old allocation that is now gone.

That's bad.

In order to allow an object to have arbitrary class invariants that the code which accesses those types can maintain, it is necessary to treat an object as something more than just the bits of its object representation. And most C++ types maintain some invariant for which its object representation cannot survive bitwise copying.

like image 121
Nicol Bolas Avatar answered Oct 16 '22 18:10

Nicol Bolas


You cannot change the storage of an existing object in C++. The only what you can do is to create new objects — in "reallocated" memory — that will have the same content as the original objects. This is exactly what std::vector is capable of.

A Problem with C++ is that this functionality involves generally much more than just copying bytes. Copying the content of objects by copying their binary representation is enabled only for a limited set of types — so-called trivially-copyalbe types. For the other ones, copy/move constructors and destructors need to be involved.

like image 42
Daniel Langr Avatar answered Oct 16 '22 19:10

Daniel Langr