局部变量内存和malloced内存位置
我正在玩malloced内存和局部变量,以查看堆栈和堆的增长情况。 根据我的理解,堆向上生长,堆栈向下生长。 所有使用malloc分配的内存都分配在堆中,并且局部变量在堆栈中分配到一个函数中。
在以下程序中:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 999999999
void tot(){
static int c =0;
int k;
c++;
int *pp = malloc(sizeof(int) * SIZE);
if(pp==NULL){
fprintf(stderr,"NO memory allocated after call : %dn",c);
return;
}
printf("%p %d %pn",&k,c,pp);
tot();
}
int main(int argc, char *argv[]){
int k;
int *pp = malloc(sizeof(int) * 99999);
if(pp ==NULL){
fprintf(stderr,"No memory allocatedn");
return;
}
printf("%p %pn",&k,pp);
tot();
return 0;
}
我在函数tot()中创建了一个局部变量,它将是4个字节和一个类型为int *的指针变量,这会将每个调用的堆栈总大小增加到略大于4个字节。 我也使用malloc分配了一些内存,并将分配的内存分配给本地指针变量。 由于这个malloced内存是分配在堆上的,所以堆栈大小应该仍然超过4个字节,但根据我在上述程序中的观察,堆栈大小会增加很多。 在大量的数学运算后,我发现堆栈框架包含了在每个函数调用中创建的malloced内存。
虽然删除线
int *pp = (int*)malloc(sizeof(int) * SIZE);
它负责在每个函数调用中分配这个大内存,将堆栈帧大小减少到4个字节,这非常好。
尽管在两种情况下堆栈帧都在向下增长。
为什么我得到这样的输出。 我相信动态内存是分配在堆上是错误的。 为什么malloced内存正在增加堆栈帧的大小?
编辑:我也尝试访问分配的内存在一个堆栈帧在其他堆栈帧通过将指针传递给一个堆栈帧中分配给另一个函数调用(另一个堆栈帧)的内存,以便分配在一个帧中的内存可以用于其他调用只是为了验证编译器是否不在内部将malloc转换为alloca(这可能是大型堆栈帧的原因),但没有任何区别。 结果仍然相同。
许多Linux系统都有ASLR,所以malloc
的结果可能不会从一次执行到下一次执行再现; 您可以禁用ASLR thru /proc/sys/kernel/randomize_va_space
。
实际上,最近的malloc实现比sbrk
或brk
更多地使用mmap(2)系统调用。 所以堆实际上是由几个不连续的虚拟内存段组成的。 通常,稍后调用free
malloc
标记释放的区域是可重用的(但不一定需要munumap(2)
)。
您可以通过查看/proc/1234/maps
来查看某个pid 1234进程的地址空间。 阅读proc(5)手册页(并尝试使用cat /proc/self/maps
来显示运行该cat
的进程的地址空间)。
你tot
功能是尾递归,最GCC编译将优化它作为一个循环......(如果您正在使用编译gcc -O1
或更多)。 然而,堆栈帧通常需要对齐(例如16字节),并且还包含前一帧指针,一些空间来溢出寄存器等。
C是一种低级语言,但它仍然足够松散地定义了具体细节可能会因平台而异的事物。 例如,只要运行程序的结果没有改变,编译器就可以自由地分配不同数量的堆栈空间(通常是“额外”空间)。
这可以以表演[1]的名义完成,或支持某些调用约定。 所以即使int只需要空间字节,编译器也可以在堆栈上分配16个字节以保持有利的内存对齐。
如果堆栈大小的“大”增加与SIZE相比较小,则差异可能仅仅是由于这种填充。 (请注意,堆栈中的数据不仅仅局部变量 - 调用函数的返回地址通常会存储在那里,以及编译器决定应从调用者存储的任何寄存器的内容。)
如果它实际上看起来像malloc
分配给堆栈(即堆栈正在增加SIZE跳转),这是令人惊讶的,但可能仍然代表编译器“正确”。 按定义malloc
分配内存; 不能保证这是从堆中分配的,尽管这当然是正常的实现。 由于malloc
的结果永远不会在调用它的堆栈框之外访问,因此编译器原则上可以将其优化为alloca
调用; 但是,再一次,我很惊讶地看到这一点。
[1]示例:http://software.intel.com/en-us/articles/data-alignment-when-migrating-to-64-bit-intel-architecture
链接地址: http://www.djcxy.com/p/82519.html