C语言内存管理

内存分配方式
  • 静态存储区

全局变量 static 变量

  • 栈 效率高

函数内局部变量

堆和栈:
栈:编译器分配
堆:程序员手动分配
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低

内存错误
  • 未成功分配
assert(p!=NULL)  
if(p==NULL)
  • 成功分配,未初始化
    默认值不一定是0,进行必要的初始化和赋零工作
    e. 数组没有初始化

  • 越界

  • 忘记释放内存,内存泄漏

  • 操作已经释放的内存

    • 野指针,free/delete之后没有置为 NULL
    • 返回“栈”上的指针/引用
    • 调用关系复杂,需重新设计数据结构

指针变量在创建的同时应当被初始化,要么将指针设置为 NULL,要么让它指向合法的内存。

char *p = NULL;
char *p = (char*)malloc(100);

delete 之后要设置为 NULL ,避免指向一段被释放的内存,同时不要释放已释放的内存,结果是不确定的,但如果设置为 NULL,对空指针使用 delete 是安全的。
同理,free也是一样的。如果 pNULL 指针,那么 freep 无论操作多少次都不会出问题。如果 p 不是 NULL 指针,那么 freep 连续操作两次就会导致程序运行错误。

Notice:

1. malloc/new申请内存之后,应立即检查指针是否为NULL,防止使用NULL的内存
2. 数组和动态内存赋初值
3. 注意可能越界的操作
4. 动态内存的申请和释放要对应,防止内存泄漏
5. free/delete之后要置为NULL,防止野指针产生
指针和数组对比
  • 数组

数组名对应着一块内存,其地址和容量在生命期内保持不变,地址中的内容可以改变

函数返回指针时 不要 return 栈内存指针

char *GetString(void)
{
   char p[] = "hello world";
   return p; // 编译器将提出警告
}
malloc/free 和 new/delete

对于非内部数据类型的对象而言,光用 malloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于 malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free

所以我们不要企图用 malloc/free 来完成动态对象的内存管理,应该用new/delete。由于内部数据类型的“对象”没有构造与析构的过程,对它们而言 malloc/freenew/delete 是等价的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值