内存管理和泄露

本文详细解析了程序中的内存分配原理,包括不同区域如栈、堆、全局初始化区等的作用及特点。探讨了new/delete与malloc/free的区别及其在内存管理中的应用,并强调了常量存储位置与内存泄漏的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于程序分配内存空间的简单实例如下

int a = 0; //全局初始化区
char *p1; //全局未初始化区

int main() { 

	int b; //栈
	char s[] = "abc"; //栈
	char *p2; //栈
	char *p3 = "123456"; //123456//0在常量区,p3在栈上。
	static int c =0;//全局(静态)初始化区
	p1 = new char[10]; 
	p2 = new char[20]; 
	//分配得来得和字节的区域就在堆区。
	strcpy(p1, "123456"); //123456//0放在常量区,编译器可能会将它与p3所指向的/"123456/"优化成一个地方。

}

注意,所有程序中出现的常量,或者作为直接数被编码在二进制指令中,或者存放在常量区。

若直接在栈上分配数组,所使用的数组名实际上为一个常量指针。很显然,在堆栈中分配数组时,数组名本身不是一个变量也不占内存存储空间。

程序运行时和存储时的内存模型如下:


(1)new delete

一般大家都知道sizeof不是函数,而是一个关键字(运算符),而且其返回值在编译时就被确定了。new和delete也是关键字,然而相对于sizeof来说,其机制更为复杂。实际上,无论用于调用new还是malloc,都相当于是向操作系统申请资源,资源管理器返回句柄,并同时做记录,为释放时做准备。也有可能向gcc一样,是额外在前面添加大小信息,在申请释放内存时,会向前偏移几个字节得到该块内存所对应的大小。显然,对于第二种方法,对程序员要求高,一旦访问越界破坏了标记就会出现错误。

new出来的对象一定是放在堆上。new返回值一定是一个指针。

明确一点,new/delete new[]/delete[]一定要配套使用。

原因是,无论如何使用delete,程序都可以自动释放为对象数组或为内置类型数组所分配的内存空间。但是,程序却不知道在对象数组中究竟包含几个对象而所需要调用几个析构函数。

(2)malloc free

new和delete是运算符,而malloc和free则是两个标准库函数。更为显著的特点是,malloc和free和构造函数和析构函数无关。实际上new delete等同于调用构造函数和析构函数在调用malloc和free。

内存泄露是申请内存但是没有释放而造成的。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值