C++动态内存创建与内存管理学习笔记[1]

1 内存空间逻辑组织

A 静态数据区:内存在程序启动的时候才被分配,而且可能直到程序开始执行的时候才被初始化,如函数中的静态变量就是在程序第一次执行到定义该变量的代码时才被初始化。所分配的内存在程序的整个运行期间都存在,如全局变量,static变量等。

注意:初始化的全局变量和静态变量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被初始化的对象存储区可以通过void*来访问和操纵,程序结束后由系统自行释放。

B 代码区:存放函数体的二进制代码;

C 栈区:存放自动变量。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元由编译器自动释放,超出其作用域外的操作没有定义。栈内存分配运算内置于处理器的指令集中,效率很高,但分配的内存容量有限。栈存放函数的参数值,局部变量的值等。

D 堆区(自由存储区):在运行的时候调用程序(如C中的mallocC++中的new)分配内存,可以在任何时候决定分配内存及分配的大小,用户自己负责在何时释放内存(如用freedelete)。堆中的所有东西都是匿名的,这样不能按名字访问,而只能通过指针访问。

堆需要一种策略来保存其内存是否已分配的信息。一种策略是建立一个可用块(自由存储区)的链表,每块由malloc分配的内存块都在自己的前面标明自己的大小,一般而言都经过边界对齐(alignment)处理,堆的大小受限于计算机系统中有效的虚拟内存。

堆的末端由一个称为break 的指针来标识,当堆管理器需要更多内存时,它可以通过系统调用brksbrk来移动break指针,一般情况下不必显式地调用brk,如果分配的内存容量很大,brk会被自动调用。用于管理内存的调用有:

Mallocfree--从堆中获得内存以及把内存返回给堆;

brksbrk――调整数据段的大小至一个绝对值(通过某个增量)。

注意:程序可能无法同时调用malloc()brk(),因为如果使用了mallocmalloc希望当你调用brksbrk时,它具有唯一的控制权。由于sbrk向进程提供了唯一的方法将数据段内存返回给系统内核,所以如果使用了malloc,就有效地防止了程序的数据段缩小的可能性。

此处的堆与数据结构中的堆是两回事,它的分配方式类似于链表。

由于堆中的空间由用户负责分配及释放,因此需要注意内存泄漏的问题。

另外实际上堆区与自由存储区并不是一回事,详细信息见exceptional c++条款35

E 文字常量区(常量数据区):存放常量字符串等在编译期间就能确定的值,在程序结束后由系统自动释放。类对象不能存在于这个区域中。在本区域中所有的数据都是只读的,任何企图修改本区域数据的行为都会造成无法预料的后果。

演示内存分布的示例如下:(示例需要更改完善,同时解决其中的bug)

int a = 0;   //全局初始化区

char *p1;  //全局未初始化区

main()

{

int b;  //

char s[] = "abc";  //

char *p2;  //

char *p3 = "123456";  //123456在文字常量区,p3在栈上。(如何得到文字常量地址?)

static int c =0  //全局(静态)数据区

p1 = (char *)malloc(10);

p2 = (char *)malloc(20);   //分配得来的1020字节的区域就在堆区。(如何得到?)

strcpy(p1, "123456");   //123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值