【C++学习】C++内存管理


一、内存分配方式

1.内存区域

(1)栈
局部存储,函数生命周期结束时销毁
(2)堆
malloc与free管理
(3)自由存储区
new与delete管理,默认实现为堆,程序员可重载操作符产生其他实现
(4)全局/静态存储区
合并.data与.bss段的存储
(5)常量存储区

2.内存问题分析

1.内存碎片

频繁申请释放小块内存影响内存性能

(1)原因

  • 内部碎片:内存分配的对齐原则导致产生碎片
  • 外部碎片:频繁的分配与回收物理页面

(2)解决
对每个类重载new和delete运算符,从内存缓冲池申请空间

2.内存泄露

指针先于内存空间被释放导致内存空间无法引用和回收

(1)原因:
malloc和free不能对应使用
(2)细节
【new[ ]与delete[ ] 匹配问题】
内置类型无需匹配,自定义类型不匹配会出现内存泄露

int *p = new int[100];
delete[] p;

【堆上有指针的问题】
先释放子节点,再释放父节点

free(p->np);
free(p);

【注意多态特性】

  1. delete void*类型时不调用析构函数
//对应类型承接,delete时调用对应析构函数
//void*类型承接,delete时无析构函数调用
    Object* a = new Object(10, 'A');
    void* b = new Object(20, 'B');
    delete a; //释放a,调用析构函数
    delete b; //释放b,不调用析构函数
  1. 父类析构函数问题
//若父类析构函数是virtual,p调用子类析构函数
//若父类析构函数非虚函数,p调用父类析构函数,子类特性未释放,内存泄露
	person *p = new child(20,'B');
    delete p;

【注意指针】

//错误写法
void my_malloc(void *p, int size)
{
//p为函数创建的指针的副本,函数结束时销毁 
	p = malloc(sizeof(int)*size);  
}
//正确写法
void my_malloc(void **p, int size) or void my_malloc(void &(*p), int size)
{
	*p = malloc(sizeof(int)*size);
}

二、new与delete相关

1.概述

new{
    //分配内存,可重载 
	operator new{
		//分配堆内存 
		malloc 
	}
	//调用构造函数 
	ctor 
} 

2.细节

1.STL空间配置器

  • allocator:配置器默认实现,内部调用operator new
//C++11 改名为 new_allocator
int *p = allocator<int>().allocate(512, (int*)0);
allocate<int>().deallocate(p, 512) 
  • alloc:二级配置器实现,性能更好
//C++11 改名为__pool_alloc
vector<string, __gnu_cxx::__pool_alloc<string>> vec;
/* 
两级配置器:
(1)配置区超过128byte:一级配置器
malloc + free + set_new_handler
(2)配置区小于128byte:二级配置器
内存池 + 自由链表
*/

2.new、operator new、placement new

  • new: 内置函数, 分配空间 + 调用构造函数
    T *p = new T();

  • operator new: 可重载, 分配内存
    void *memory = operator new(sizeof(string));

  • placement new: 标准operator new, 在已有内存创建对象
    void *operator new( size_t, void * p ) throw() { return p; }
    T *pb = new(pa) T

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值