为什么动态分配的两个变量的内存位置不是连续的?
Why the Memory locations for two variables which is allocated dynamically are not consecutive?
我使用两个变量,其中内存是动态分配的,我打印内存位置,但它们不是连续的。 为什么?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int));
printf("n a=%p t b=%p n",a,b);
}
我得到的答案(在 Linux 中(是
第一次:
a=0x20a0010 b=0x20a0030
第二次:
a=0x657010 b=0x657030
第三次:
a=0x139e010 b=0x139e030
为什么a
和b
变量的内存位置之间的确切差异是第 1 次、第 2 次和第 3 次?
这与分页内存有关吗?
我的处理器是 64 位。
两个连续分配之间的间隔与分页无关。您的分配金额非常小,因此它们位于数据细分受众群中。libc 在内部处理这些 -sizeof int
字节之外的空间通常包含指向上一个和下一个数据块的指针以及分配的大小 - 毕竟free
只会得到一个指针,它需要弄清楚有多少内存要解除分配。
此外,这两个指针都与 16 字节边界对齐。C11 7.22.3 说
如果分配成功,则返回的指针将适当对齐,以便可以将其分配给具有基本对齐要求的任何类型的对象的指针,然后用于访问分配空间中的此类对象或此类对象的数组(直到空间被显式解除分配(。
因此,即使您将它们用于int
C 标准也要求返回的指针与任何数据类型对齐 - 在您的实现中为 16 字节。
但是,如果您分配了一个非常大的对象,glibc 将使用mmap
来映射整个页面。然后对齐方式(在我的 64 位计算机上(正好是 16K 页面开头的 4 个字节:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = malloc(12345678);
int *b = malloc(12345678);
printf("n a=%p t b=%p n",a,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, 12349440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb65dbf0000
至于为什么地址从一个执行不断变化到另一个执行 - 这是由于地址空间布局随机化或ASLR - 一种安全机制,使邪恶破解者更难预测地利用代码中的未定义行为。
附言如果确实需要在连续地址动态分配 2int
s 的空间,请分配一个数组。
操作系统处理内存分配,并且在动态分配两个连续变量时,无法保证此内存是连续的。我还应该提到,这是被称为ASLR的防御机制的结果。ASLR 通过在进程执行期间随机化进程的位置来防止缓冲区溢出,这可能包括堆栈、堆和库。这就是您注意到这些地址更改的原因。按照标准,您只能保证以下内容。
ISO C11 7.22.3.4 马洛克
1(剧情简介
#include <stdlib.h>
void* malloc(size_t size);
2(描述malloc 函数为大小由大小指定且其值不确定的对象分配空间。
3(退货malloc 函数返回空指针或指向已分配空间的指针。
正如 GNU 中注释的那样 malloc 的例子
请注意,位于块末尾之后的内存可能会 用于其他用途;也许是已经分配的块 另一个打电话给马洛克。
这实际上意味着,对于每次调用malloc
操作系统,根据其内存管理算法,为调用方找到最合适/适当/最合适的/有效的可用空间。
例如:
void* p_1 = malloc(4);
void* p_2 = malloc(4);
[oooo][xxxx][oooo][oooo]
^ ^
p_1 p_2
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 内存所有位置 wxWidgets
- 为什么字符串的 move() 会改变内存中底层数据的位置?
- 如何在不等待检索的情况下获取C++中的内存位置?
- 内存中类位置的成员是否取决于类成员在类定义中的位置?
- 向量的内存位置不连续
- 如何根据C++在同一内存位置重新初始化 C# 中的对象(还是自动完成)?
- 常量引用的内存位置
- C++强制变量到一个固定的内存位置
- 为什么未初始化的内存位置的值给出 -842150451 的值?
- 为什么存储在内存位置的值会发生变化?
- 在特定内存位置构造 c++ 对象
- 如果不初始化结构中的向量,它会自动为空还是具有随机内存位置的值?
- 如何识别内存泄漏的位置
- 内存位置出现Microsoft C++异常:std::out_of_range
- 函数,返回变量c++占用的内存位置的大小
- 在尝试使用CUDA分配内存时,我遇到了访问冲突写入位置错误
- delete如何知道对象在内存中的起始位置
- 无法在 Opencv 中显示图像导致内存位置
- 如何修复<程序名称>中的"<内存位置>未处理的异常。Visual Studio 2017 中的访问冲突写入位置<内存位置>"