动态内存管理补充

一、定义指针类型时尽量避免void *类型的出现,因为在后期delete指针的时候,如果指针类型为void *类型,不会调用析构函数

二、悬浮指针(野指针,无效指针),多出现于函数实现较复杂的情况

T * p = new T;
delete p;
p->f();//错误

解决方案:

  • 尽量紧贴着}(作用域结尾的大括号)写delete p;
  • 如果在delete p;之后还有代码,建议将p 的值赋为nullptr,这样如果有p->f();的话会明确报错。

三、内存泄漏(new后忘记delete):

T * p = new T;
return ;
  • 尽量保持new和delete在同一个作用域。

四、定位分配:

  • 根据指定内存起始位置,构建对象。
  • 不新分配空间,只在分配空间上构建。
  • 已分配空间,可以在栈区,也可以在堆区,但不能在程序区
struct A{
	A(int v) : n(v){}
	int n;
};

int main()
{
	char data[sizeof(a) * 3];
	A * pA1 = new(data)A(1);//在数组的首地址处调用A的有参构造函数创建一个A对象
	A * pA2 = new(pA1 + 1)A(2);//在data偏移一个A的字长的位置创建
	A * pA3 = new(pA1 + 2)A(3);

	cout << pA2->n << endl;
	pA1->~A();
	pA2->~A();
	pA3->~A();
	return 0;
}

目前只在定位分配中,析构函数需要手动调用!(如果这里不手动调用,则系统不会调用析构函数,但内存仍会释放。因为main()函数创建在栈区,结束后会自动释放内存。如果析构函数为空则没有问题,但如果不为空可能会造成内存泄漏或其他问题。)

你可能感兴趣的:(c++基础,笔记,c++,开发语言)