Memory C+中的进程内存映射+; #包括 int main(int argc,字符**argv){ int*heap_var=newint[1]; /* *页面大小4KB==4*1024==4096 */ heap_var[1025]=1; std::cout

Memory C+中的进程内存映射+; #包括 int main(int argc,字符**argv){ int*heap_var=newint[1]; /* *页面大小4KB==4*1024==4096 */ heap_var[1025]=1; std::cout,memory,memory-management,new-operator,heap-memory,Memory,Memory Management,New Operator,Heap Memory,平台分配器可能分配的内存远远大于页面大小,因为它计划使用内存“bucket”对于其他分配或可能保持某些内部状态,可能在发布版本中存在远远不止一个页面大小的虚拟内存块。您也不知道在该特定页面中分配了内存的位置(您可以通过屏蔽一些位来了解),而且不提平台/架构(我假设x86_64)这个页面甚至是4kb都不知道,它可能是一个2MB的“巨大”页面或任何类似的页面 但通过访问外部数组边界,您触发了未定义的行为,如读取时崩溃或写入时数据损坏 不要使用你没有的记忆 我也应该提到,这可能与C++无关,因为 Ne

平台分配器可能分配的内存远远大于页面大小,因为它计划使用内存“bucket”对于其他分配或可能保持某些内部状态,可能在发布版本中存在远远不止一个页面大小的虚拟内存块。您也不知道在该特定页面中分配了内存的位置(您可以通过屏蔽一些位来了解),而且不提平台/架构(我假设
x86_64
)这个页面甚至是4kb都不知道,它可能是一个2MB的“巨大”页面或任何类似的页面

但通过访问外部数组边界,您触发了未定义的行为,如读取时崩溃或写入时数据损坏

不要使用你没有的记忆

我也应该提到,这可能与C++无关,因为<代码> NeX[]/Cuff>操作符通常只调用核心平台库中的“代码> MalcC <代码> /<代码> CaloC后台。(可以是OSX上的

libSystem
,或
glibc
musl
或Linux上的其他任何东西,甚至是拦截分配器)。您遇到的SEGFULT通常来自堆块周围的保护页,或者在没有保护页的情况下,仅使用未映射内存


NB:不要在家里尝试这一点:在某些情况下,您可能会故意触发通常被视为未定义的行为,但在特定的平台上,您可能确切知道其中的内容(一个很好的例子是在Linux上滥用
pthread\u t
opaque来获得
tid
,而不需要额外的系统调用开销,但您必须确保使用正确的libc、该libc的正确构建类型、该libc的正确版本、该libc构建时使用的正确编译器等).

平台分配器的分配可能远远超过页面大小,因为它计划使用内存“bucket”对于其他分配或可能保持某些内部状态,可能在发布版本中存在远远不止一个页面大小的虚拟内存块。您也不知道在该特定页面中分配了内存的位置(您可以通过屏蔽一些位来了解),而且不提平台/架构(我假设
x86_64
)这个页面甚至是4kb都不知道,它可能是一个2MB的“巨大”页面或任何类似的页面

但通过访问外部数组边界,您触发了未定义的行为,如读取时崩溃或写入时数据损坏

不要使用你没有的记忆

我也应该提到,这可能与C++无关,因为<代码> NeX[]/Cuff>操作符通常只调用核心平台库中的“代码> MalcC <代码> /<代码> CaloC后台。(可以是OSX上的

libSystem
,或
glibc
musl
或Linux上的其他任何东西,甚至是拦截分配器)。您遇到的SEGFULT通常来自堆块周围的保护页,或者在没有保护页的情况下,仅使用未映射内存

NB:不要在家里尝试这一点:在某些情况下,您可能会故意触发通常被视为未定义的行为,但在特定的平台上,您可能确切知道其中的内容(一个很好的例子是在Linux上滥用
pthread\u t
opaque来获得
tid
,而不需要额外的系统调用开销,但是您必须确保使用正确的libc、正确的libc构建类型、正确的libc版本、正确的编译器等)

#include <iostream>

int main(int argc, char** argv) {
  int* heap_var = new int[1];
  /*
   * Page size 4KB == 4*1024 == 4096
   */
  heap_var[1025] = 1;
  std::cout << heap_var[1025] << std::endl;
  return 0;
}

// Output: 1