Zero initialization data using an initialized array value

Will the following code correctly be null - initialize the memory returned from malloc ?

 #include <cstdlib> #include <new> int main() { char* p = new (std::malloc(10)) char[10]{}; } 
+7
c ++ c ++ 11
source share
2 answers

Yes, it will zero initialize memory because of {} at the end of the line, until malloc gets out of the new allocation. Here is an alternative version that more fully proves this point.

 #include <iostream> #include <cassert> #include <new> char mongo[10]; int main() { for (int i=0; i < 10; ++i) mongo[i] = 'a'; char *p = new (mongo) char[10]{}; for (int i= 0; i < 10; ++i) assert(p[i] == '\0'); } 

This program will start and will not print anything, because the mongo array (with the alias p ) is explicitly cleared by initializing p . On the contrary, if we omit {} at the end of this line, the program will approve and terminate.

Please note that in your version using malloc you will have to explicitly destroy the object - that part of the responsibility that comes with the new placement and among several times in modern C ++ where you need to explicitly call the destructor.

If, as in your specific case, you allocate memory using malloc() , you should return the corresponding free(p) or your program will leak memory.

Elephant in the room

(Thanks, @TC, for pointing out a lot of grayness!) Here is an explanation and an example directly from the standard (section 5.3.4):

Example:

new T calls operator new(sizeof(T)) ,

new(2,f) T calls operator new(sizeof(T),2,f) ,

new T[5] calls operator new[](sizeof(T)*5+x) and

new(2,f) T[5] calls the operator new[](sizeof(T)*5+y,2,f) .

Here x and y are non-negative indefinite values ​​representing the distribution costs of the array; the result of the new expression will be compensated by this sum from the value returned by operator new[] . This overhead can be used in all new array expressions, including references to the new[](std::size_t, void*) function library operator new[](std::size_t, void*) and other distribution functions. The amount of overhead can vary from one new call to another.

In other words, if you use the new placement for one object, everything is fine and there is no overhead imposed, but if you place an array through the placement of new , be overhead, and this may not even be the same as from call to call.

+7
source share

This is a very, very bad idea.

Currently, the new placement array, like all expressions in the new array, allows you to add an indefinite amount of overhead. There is no portable way for a program to know how many bytes this is overhead.

Therefore, if the overhead of the distribution of the implementation array for char[10] is zero, your code has undefined behavior.

If the pointer points to enough memory to accommodate all the elements of the array plus an indefinite amount of overhead (and this is very large, if there is no portable way for you to make sure), then the expression will really be zero-initialized memory.

+5
source share

All Articles