Skip to content

Why does new int[n] read 0 on one machine and garbage on another?

howto · cpp, undefined-behaviour, initialisation

new T[n] default-initialises, and for built-in types that does nothing: the elements hold whatever bytes were there, and reading one is undefined behaviour. Write new T[n]{} to value-initialise to zero, or better, use std::vector, which zeroes anyway.

On Linux and macOS a fresh allocation often comes from pages the OS handed over zeroed, so the read prints 0 until that memory is reused. MSVC’s debug heap fills fresh allocations with 0xcd, so the same read prints -842150451 there. Both are the quiet kind of undefined behaviour: it “works on my machine”.

data_(new int[size]) // indeterminate contents
data_(new int[size]{}) // value-initialised: all zeros. One pair of braces.

In C# new int[5] is always zeroed; the runtime guarantees it. C++ makes zeroing opt-in because it costs a memset, and the contract is “don’t pay for what you don’t use”.

Habit: every new T[n] gets {} unless a measured reason says otherwise, and in real code prefer std::vector, which value-initialises its elements.

Source: https://mkhomutov.github.io/going-unmanaged/25-findings-from-practice/#finding-7--new-tn-does-not-zero-indeterminate-values-are-ub-to-read