Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operator new initializes memory to zero

There is such code:

#include <iostream>  int main(){   unsigned int* wsk2 = new unsigned int(5);   std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl;   delete wsk2;   wsk2 = new unsigned int;   std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl;   return 0; } 

Result:

wsk2: 0x928e008 5 wsk2: 0x928e008 0 

I have read that new doesn't initialize memory with zeroes. But here it seems that it does. How does it work?

like image 785
scdmb Avatar asked Sep 25 '11 15:09

scdmb


People also ask

Does new set memory to zero?

Yes. That's kind of my point. If you make a new variable and see that's it's zero, you can't straight away assume that something within your program has set it to zero. Since most memory comes ready-zeroed, it's probably still uninitialised.

Which of the following will initialize the new memory to 0?

Given a pointer and number of bytes, memset initializes all bytes to zero.

Does new initialize array to zero?

The array will be initialized to 0 in case we provide empty initializer list or just specify 0 in the initializer list. Designated Initializer: This initializer is used when we want to initialize a range with the same value.


2 Answers

There are two versions:

wsk = new unsigned int;      // default initialized (ie nothing happens) wsk = new unsigned int();    // zero    initialized (ie set to 0) 

Also works for arrays:

wsa = new unsigned int[5];   // default initialized (ie nothing happens) wsa = new unsigned int[5](); // zero    initialized (ie all elements set to 0) 

In answer to comment below.

Ehm... are you sure that new unsigned int[5]() zeroes the integers?

Apparently yes:

[C++11: 5.3.4/15]: A new-expression that creates an object of type T initializes that object as follows: If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed, the object has indeterminate value. Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.

#include <new> #include <iostream>   int main() {     unsigned int   wsa[5] = {1,2,3,4,5};      // Use placement new (to use a know piece of memory).     // In the way described above.     //      unsigned int*    wsp = new (wsa) unsigned int[5]();      std::cout << wsa[0] << "\n";   // If these are zero then it worked as described.     std::cout << wsa[1] << "\n";   // If they contain the numbers 1 - 5 then it failed.     std::cout << wsa[2] << "\n";     std::cout << wsa[3] << "\n";     std::cout << wsa[4] << "\n"; } 

Results:

> g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.2.0 Thread model: posix > g++ t.cpp > ./a.out 0 0 0 0 0 > 
like image 118
Martin York Avatar answered Oct 07 '22 17:10

Martin York


operator new is not guaranteed to initialize memory to anything, and the new-expression that allocates an unsigned int without a new-initializer leaves the object with an indeterminate value.

Reading the value of an uninitialized object results in undefined behavior. Undefined behavior includes evaluating to the value zero with no ill effects but could result in anything happening so you should avoid causing it.

In C++11, the language used is that the allocated objects are default-initialized which for non-class types means that no initialization is performed. This is different from the meaning of default-initialized in C++03.

like image 35
CB Bailey Avatar answered Oct 07 '22 17:10

CB Bailey