{"id":45181,"date":"2015-07-09T07:00:00","date_gmt":"2015-07-09T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20150709-00\/?p=45181\/"},"modified":"2019-03-13T12:17:10","modified_gmt":"2019-03-13T19:17:10","slug":"20150709-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150709-00\/?p=45181","title":{"rendered":"Why is my x64 process getting heap address above 4GB on Windows 8?"},"content":{"rendered":"<p>A customer noticed that when they ran their program on Windows&nbsp;8, memory allocations were being returned above the 4<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2009\/06\/11\/9725386.aspx\">GB<\/a> boundary. They included a simple test program: <\/p>\n<pre>\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n\nint main(int argc, char** argv)\n{\n    void *testbuffer = malloc(256);\n    printf(\"Allocated address = %p\\n\", testbuffer);\n    return 0;\n}\n<\/pre>\n<p>When run on Windows&nbsp;7, the function prints addresses like <code>0000000000179B00<\/code>, but on Windows&nbsp;8, it prints addresses like <code><u>00000086<\/u>E60EA410<\/code>. <\/p>\n<p>The customer added that they care about this difference because pointers above 4GB will be corrupted when the value is truncated to a 32-bit value. As part of their experimentation, they found that they could force pointers above 4GB to occur even on Windows&nbsp;7 by allocating very large chunks of memory, but on Windows&nbsp;8, it&#8217;s happening right off the bat. <\/p>\n<p>The memory management team explained that this is expected for applications linked with the <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/jj835761.aspx\"><code>\/HIGH&shy;ENTROPY&shy;VA<\/code> flag<\/a>, which the Visual Studio linker enables by default for 64-bit programs. <\/p>\n<p>High-entropy virtual address space is more commonly known as Address Space Layout Randomization (ASLR). ASLR is a feature that makes addresses in your program less predictable, which significantly improves its resiliance to many categories of security attacks. Windows&nbsp;8 expands the scope of ASLR beyond just the code pages in your process so that it also randomizes where the heap goes. <\/p>\n<p>The customer accepted that answer, and that was the end of the conversation, but there was something in this exchange that bothered me: The bit about truncating to a 32-bit value. <\/p>\n<p>Why are they truncating 64-bit pointers to 32-bit values? That&#8217;s the bug right there. And they even admit that they can trigger the bug by forcing the program to allocate a lot of memory. They need to stop truncating pointers! Once they do that, all the problems will go away, and it won&#8217;t matter where the memory gets allocated. <\/p>\n<p>If there is some fundamental reason that they have to truncate pointers to 32-bit values, then they should build <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/08\/17\/215682.aspx\">without <code>\/LARGEADDRESSAWARE<\/code><\/a> so that the process will be given an address space of only 2GB, and then they can truncate their pointers all they want. <\/p>\n<p>(Of course, if you&#8217;re going to do that, then you probably should just compile the program as a 32-bit program, since you&#8217;re not really gaining much from being a 64-bit program any more.) <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why shouldn&#8217;t it?<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-45181","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Why shouldn&#8217;t it?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=45181"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45181\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=45181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=45181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=45181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}