3

We've recently discovered a serious bug in our software that was caused by assuming that a dynamically allocated array was initialized to zero (while it wasn't). So the problem was something like this:

int* foo = new int[1];
foo[0] += 10;

I'm now trying to estimate the impact of this since we also recently had a few changes in our environment: We started using new processing units which run a different OS (Win XP before, which are still used, now in addition to that some new units running Win 8).

There appears to be no problem with the computations running on the Win XP machines, but on Win 8 the same binaries produce gibberish. So the compiler does not initialize these arrays (these were optimized builds) but it seems like Windows XP does initialize newly allocated memory to zeros (while Windows 8 does not). Is this somewhere documented? Can I trust in this so that I can assume this problem did not affect all computations previously executed on the Win XP machines?

Niko
  • 26,516
  • 9
  • 93
  • 110
  • Have you started using new IDEs as well? – dmg Feb 05 '15 at 14:12
  • Just add `()` at the end of each such allocation, to zero the array. There should be no need to re-run unit-tests etc. Relying on OS guarantees would be risky at best in the first place, and not a way forward anyway when you know you have to support a platform (Win 8) where you know there's no such guarantee. – Cheers and hth. - Alf Feb 05 '15 at 14:14
  • What platform are you compiling your program on? – AStopher Feb 05 '15 at 14:14
  • @dmg We've switched compilers a few months ago, yes. But in this case, the same binaries were run on both types of processing units. – Niko Feb 05 '15 at 14:15
  • 1
    @ʎǝʞuoɯɹǝqʎɔ We're compiling on Windows 7. – Niko Feb 05 '15 at 14:15
  • @Niko was it this exact example which was causing the problem or was it more like `int foo[1]; foo[0] += 10`? – sjdowling Feb 05 '15 at 14:15
  • @sjdowling No, the code used "new T[n]" as in my example. – Niko Feb 05 '15 at 14:19
  • Microsoft Visual C++ comes bundled with CRT source code. Check it out to see what OS API function call is used by `operator new` and then check MSDN for the description of that function to see if it documents filling allocated memory with zeroes. – PowerGamer Feb 05 '15 at 14:20
  • @PowerGamer It isn't the operating system which handles allocation and initialisation of memory for `new`, that will be the CRT, presumably the OP is bundling the same CRT with their program. – sjdowling Feb 05 '15 at 14:22
  • @sjdowling CRT allocates memory by calling some WinAPI function. Zero initialization of memory happens only under WinXP - so it is not the CRT that zero initializes the memory but the OS function that did the allocation. The only place where such zero-initialization can be documented for OS API function is MSDN. – PowerGamer Feb 05 '15 at 14:29

1 Answers1

5

Zero initialization of pages new to the process happens in all Windows versions. It would be a security failure to do otherwise. However, depending on address space layout, new requests may or may not be satisfied by recycled allocations. And since Vista, address space is randomized.

But it's indeed possible that due to some event outside your control, you may have gotten a recycled memory page from new int[] even on XP. That could even have been a page initially allocated to your process in reaction to some OS call you made, e.g. to convert an ANSI string to UTF-16 when you called MessageBoxA(). You really can't assume that all memory that's new to you is new to your process.

MSalters
  • 173,980
  • 10
  • 155
  • 350