{"id":108907,"date":"2023-10-19T07:00:00","date_gmt":"2023-10-19T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=108907"},"modified":"2023-10-19T07:02:34","modified_gmt":"2023-10-19T14:02:34","slug":"20231019-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20231019-00\/?p=108907","title":{"rendered":"What&#8217;s the difference between setting a page&#8217;s protection to <CODE>PAGE_NOACCESS<\/CODE> and freeing it?"},"content":{"rendered":"<p>A customer wanted to know if, after using <code>Virtual\u00adAlloc<\/code> with <code>MEM_<wbr \/>COMMIT<\/code> to commit some memory, they could free parts of it by calling <code>Virtual\u00adProtect<\/code> with <code>PAGE_<wbr \/>NO\u00adACCESS<\/code>.<\/p>\n<p>No, changing a page to no-access does not free it. It makes the page inaccessible, but it&#8217;s still there. If you can restore access later, the old contents will still be there.<\/p>\n<pre>SYSTEM_INFO info;\r\nGetSystemInfo(&amp;info);\r\n\r\n\/\/ Allocate two pages of read-write data\r\nauto p = (BYTE*)VirtualAlloc(\r\n    nullptr, info.dwPageSize * 2,\r\n    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);\r\n\r\n\/\/ Set the first byte to 1\r\np[0] = 1;\r\n\r\n\/\/ Remove access from the first page\r\nDWORD prev;\r\nVirtualProtect(p, info.dwPageSize, PAGE_NOACCESS, &amp;prev);\r\n\r\n\/\/ At this point, any access to p[0] will crash with an access violation.\r\n\r\n\/\/ Restore access to the memory.\r\nVirtualProtect(p, info.dwPageSize, PAGE_READWRITE, &amp;prev);\r\n\r\n\/\/ The old values are still there!\r\nASSERT(p[0] == 1);\r\n<\/pre>\n<p>If you want to free the memory, you can use <code>Virtual\u00adFree<\/code> with the <code>MEM_<wbr \/>DECOMMIT<\/code> flag.<\/p>\n<pre>\/\/ Allocate two pages of read-write data\r\nauto p = (BYTE*)VirtualAlloc(\r\n    nullptr, info.dwPageSize * 2,\r\n    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);\r\n\r\n\/\/ Set the first byte of each page to 1\r\np[0] = 1;\r\np[info.dwPageSize] = 1;\r\n\r\n\r\n\/\/ Decommit the first page\r\nDWORD prev;\r\nVirtualFree(p, info.dwPageSize, MEM_DECOMMIT);\r\n\r\n\/\/ The memory is now gone!\r\n\/\/ At this point, any access to p[0] will crash with an access violation.\r\n\r\n\/\/ Commit a new page.\r\nVirtualAlloc(p, info.dwPageSize,\r\n    MEM_COMMIT, PAGE_READWRITE);\r\n\r\n\/\/ The old values are gone!\r\nASSERT(p[0] != 1);\r\n\r\n\/\/ But the second page is still good.\r\nASSERT(p[info.dwPageSize] == 1);\r\n<\/pre>\n<p>If you unreserve a region of address space with <code>Virtual\u00adFree(..., MEM_<wbr \/>RELEASE)<\/code>, then all the associated memory in the region is decommitted as part of the release.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nobody can access it, but it&#8217;s still there.<\/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-108907","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Nobody can access it, but it&#8217;s still there.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108907","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=108907"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108907\/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=108907"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=108907"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=108907"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}