微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么dynamic分配的两个variables的内存位置不连续?

我使用两个variables,其中dynamic分配内存,并打印内存位置,但它们不是连续的。 为什么?

#include <stdio.h> #include <stdlib.h> int main() { int *a = malloc(sizeof(int)); int *b = malloc(sizeof(int)); printf("na=%p tb=%p n",a,b); }

我得到的答案(在Linux中)是

第一次:

a=0x20a0010 b=0x20a0030

第二次:

如何在C ++中获取DLL文件的版本信息

并发访问大量的项目

Windows进程和它连接到的IP地址

是否可以使用另一个进程创build的HWND?

C ++在公共函数中使用system()安全还是不安全?

a=0x657010 b=0x657030

第三次:

a=0x139e010 b=0x139e030

为什么a和bvariables的存储位置在第一,第二和第三时间的确切区别?

这与分页内存有关吗?

我的处理器是64位。

上下文切换function与中断呼叫?

防止窗口出现任何本机代码未处理的exception对话框

如何从stdin编译代码

全局键盘钩会触发两次

在Linux上从C调用C#

两个连续分配之间的差距与寻呼无关。 您的分配太小,以至于它们驻留在数据段中。 Libc在内部处理这些内容 – sizeof int字节之外的空间一般包含指向前一个和下一个数据块的指针以及分配的大小 – 毕竟free只是获得一个指针,并且需要弄清楚它有多少内存释放。

另外这两个指针都对齐到16字节的边界。 C11 7.22.3说

如果分配成功,返回的指针被适当地对齐,以便它可以被分配给具有基本对齐要求的任何类型的对象的指针 ,然后用于访问分配的空间中的这样的对象或这样的对象的数组(直到空间被明确解除分配)。

因此,即使你将它们用于int ,C标准也要求返回的指针对齐任何数据类型 – 在你的实现上它是16字节。

但是,如果分配一个非常大的对象,glibc将使用mmap来映射整个页面。 然后,对齐方式(在我的64位计算机上)从4K页面的开始就是16个字节:

#include <stdio.h> #include <stdlib.h> int main() { int *a = malloc(12345678); int *b = malloc(12345678); printf("na=%p tb=%p n",b); }

运行时

% ./a.out a=0x7fb65e7b7010 b=0x7fb65dbf0010

用strace ./a.out可以看到mmap调用 – 那里有其他的系统调用

mmap(NULL,12349440,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7fb65e7b7000 mmap(NULL,0) = 0x7fb65dbf0000

至于为什么这些地址不断地从一个执行改变到另一个 – 这是由于地址空间布局随机化,或ASLR – 一个安全机制,使得邪恶的黑客难以预测地利用你的代码中的未定义的行为 。

PS如果您确实需要在连续的地址处动态分配2个int的空间,请分配一个数组。

操作系统处理内存分配,并不保证在动态分配两个连续变量时该内存是连续的。 我还应该提到,这是一种被称为ASLR的防御机制的结果。 ASLR通过随机化进程的位置来防止缓冲区溢出,这可能包括堆栈,堆和库 。 这就是为什么你注意到这些地址在变化。 按照标准,你只能保证以下。

ISO C11 7.22.3.4 Malloc

1) 简介

#include <stdlib.h> void* malloc(size_t size);

2) 描述 malloc函数为大小由大小指定且值不确定的对象分配空间。

3) 返回 malloc函数返回一个空指针或一个指向分配空间的指针。

注意在malloc的GNU例子

请注意,位于块尾部的内存很可能会用于其他内容; 也许是另一个调用malloc已经分配的块。

这实际上意味着,对于每次调用malloc操作系统,根据其内存管理算法,为调用者找到最合适的/合适的/合适的/有效的空闲空间。

例如:

void* p_1 = malloc(4); void* p_2 = malloc(4); [oooo][xxxx][oooo][oooo] ^ ^ p_1 p_2

如果你想连续的内存分配内存和unique_ptr与两个数组的大小,并指出你的指针的末尾和指针的中心,你从独特的指针得到。 只记得不要删除你的a和b指针。

std::unique_ptr<int> a(new int[na+nb]) int * aptr = a.get(); Int * bptr = a.get() + na;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐