{"id":6083,"date":"2012-11-15T07:00:00","date_gmt":"2012-11-15T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2012\/11\/15\/if-youre-going-to-write-your-own-allocator-you-need-to-respect-the-memory_allocation_alignment\/"},"modified":"2012-11-15T07:00:00","modified_gmt":"2012-11-15T07:00:00","slug":"if-youre-going-to-write-your-own-allocator-you-need-to-respect-the-memory_allocation_alignment","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20121115-00\/?p=6083","title":{"rendered":"If you&#039;re going to write your own allocator, you need to respect the MEMORY_ALLOCATION_ALIGNMENT"},"content":{"rendered":"<p>\nThis time, I&#8217;m\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/05\/12\/10009451.aspx\">\nnot going to set up a story<\/a>.\nI&#8217;m just going to go straight to the punch line.\n<\/p>\n<p>\nA customer overrode the <code>new<\/code> operator in order to add\nadditional instrumentation.\nSomething like this:\n<\/p>\n<pre>\nstruct EXTRASTUFF\n{\n    DWORD Awesome1;\n    DWORD Awesome2;\n};\n\/\/ error checking elided for expository purposes\nvoid *operator new(size_t n)\n{\n  EXTRASTUFF *extra = (EXTRASTUFF)malloc(sizeof(EXTRASTUFF) + n);\n  extra-&gt;Awesome1 = get_awesome_1();\n  extra-&gt;Awesome2 = get_awesome_2();\n  return ((BYTE *)extra) + sizeof(EXTRASTUFF);\n}\n\/\/ use your imagination to implement\n\/\/ operators new[], delete, and delete[]\n<\/pre>\n<p>\nThis worked out okay on 32-bit systems because in 32-bit Windows,\n<code>MEMORY_ALLOCATION_ALIGNMENT<\/code> is 8,\nand <code>sizeof(EXTRASTUFF)<\/code> is also 8.\nIf you start with a value that is a multiple of 8,\nthen add 8 to it,\nthe result is still a multiple of 8,\nso the pointer returned by the custom\n<code>operator new<\/code> remains properly aligned.\n<\/p>\n<p>\nBut on 64-bit systems, things went awry.\nOn 64-bit systems,\n<code>MEMORY_ALLOCATION_ALIGNMENT<\/code> is 16,\nAs a result, the custom\n<code>operator new<\/code> handed out <i>guaranteed-misaligned<\/i> memory.\n<\/p>\n<p>\nThe misalignment went undetected for a long time,\nbut the sleeping bug finally woke up when somebody\nallocated a structure that contained an\n<code>SLIST_ENTRY<\/code>.\nAs we saw earlier,\n<!-- Why are the alignment requirements for SLIST_ENTRY so different on 64-bit Windows? -->\nthe\n<code>SLIST_ENTRY<\/code>\nreally does need to be aligned according to the\n<code>MEMORY_ALLOCATION_ALIGNMENT<\/code><\/a>,\nespecially on 64-bit systems,\nbecause 64-bit Windows takes advantage of the extra &#8220;guaranteed to be zero&#8221;\nbits that 16-byte alignment gives you.\nIf your\n<code>SLIST_ENTRY<\/code> is not 16-byte aligned,\nthen those &#8220;guaranteed to be zero&#8221; bits are not actually zero,\nand then the algorithm breaks down.\n<\/p>\n<p>\nResult: Memory corruption and eventually a crash.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This time, I&#8217;m not going to set up a story. I&#8217;m just going to go straight to the punch line. A customer overrode the new operator in order to add additional instrumentation. Something like this: struct EXTRASTUFF { DWORD Awesome1; DWORD Awesome2; }; \/\/ error checking elided for expository purposes void *operator new(size_t n) { [&hellip;]<\/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-6083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>This time, I&#8217;m not going to set up a story. I&#8217;m just going to go straight to the punch line. A customer overrode the new operator in order to add additional instrumentation. Something like this: struct EXTRASTUFF { DWORD Awesome1; DWORD Awesome2; }; \/\/ error checking elided for expository purposes void *operator new(size_t n) { [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6083","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=6083"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6083\/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=6083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=6083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=6083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}