2

I'am wondering if built-in types in objects created on heap with new will be initialized to zero? Is it mandated by the standard or is it compiler specific?

Given the following code:

#include <iostream>

using namespace std;

struct test
{
    int _tab[1024];
};

int main()
{
    test *p(new test);

    for (int i = 0; i < 1024; i++)
    {
        cout << p->_tab[i] << endl;
    }

    delete p;
    return 0;
}

When run, it prints all zeros.

kyku
  • 5,892
  • 4
  • 43
  • 51

4 Answers4

12

You can choose whether you want default-initialisation, which leaves fundamental types (and POD types in general) uninitialised, or value-initialisation, which zero-initialises fundamental (and POD) types.

int * garbage = new int[10];    // No initialisation
int * zero    = new int[10]();  // Initialised to zero.

This is defined by the standard.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    It's also good to note that for non-fundamental types, both default initialization and value-initialization (with no parameter) call the default constructor. – Mooing Duck Feb 04 '12 at 21:48
3

No, if you do something like this:

int *p = new int;

or

char *p = new char[20];  // array of 20 bytes

or

struct Point { int x; int y; };
Point *p = new Point;

then the memory pointed to by p will have indeterminate/uninitialized values.

However, if you do something like this:

std::string *pstring = new std::string();

Then you can be assured that the string will have been initialized as an empty string, but that is because of how class constructors work, not because of any guarantees about heap allocation.

Kristopher Johnson
  • 81,409
  • 55
  • 245
  • 302
  • Just because it's empty, it doesn't mean it's initialized to 0. – Luchian Grigore Feb 04 '12 at 15:38
  • 2
    But.. int *n new int[20](); with the brackets at the end is defined to initialize the memory to zero. See: http://stackoverflow.com/questions/2204176/how-to-initialise-memory-with-new-operator-in-c – Scott Langham Feb 04 '12 at 15:39
0

It's not mandated by the standard. The memory for the primitive type members may contain any value that was last left in memory.

Some compilers I guess may choose to initialize the bytes. Many do in debug builds of code. They assign some known byte sequence to give you a hint when debugging that the memory wasn't initialized by your program code.

Scott Langham
  • 58,735
  • 39
  • 131
  • 204
-1

Using calloc will return bytes initialized to 0, but that's not standard-specific. calloc as been around since C along with malloc. However, you will pay a run-time overhead for using calloc.

The advice given previously about using the std::string is quite sound, because after all, you're using the std, and getting the benefits of class construction/destruction behaviour. In other words, the less you have to worry about, like initialization of data, the less that can go wrong.

octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131