动态存储


1. new & delete

1.1 new

  • 使用new可以在程序运行时分配内存,为数据对象分配内存的通用格式为:typename * pointer_name = new typename
  • 需要指定分配的内存的存放数据类型以及指针变量关联的数据类型
  • new出来的内存没有名字,只能通过其返回的指针对其进行管理
  • 使用new分配的内存块与常规变量分配的内存区别:(1)常规变量的内存在编译时就分配好,其内存是在(stack)中;(2)使用new是在程序运行时分配内存,其内存是在(heap)或自由存储区(free store)中。
  • Q:(1)堆和栈空间有何不同?(2)new出来的内存和常规变量的内存为什么分别从堆和栈里面分配?(3)new是如何分配内存的?
  • A:暂无

1.2 delete

  • 使用delete释放内存:使用new分配的内存由delete释放。如果只有new而没有delete,将会发生内存泄漏(memory leak),即new出去的内存没有回归内存池,也就无法再次被new出去使用。
  • delete使用格式:delete 指针变量,指针变量指向的是new出来内存的地址,不能是常规变量的地址。

1.3 使用new和delete的注意事项

  • 不要使用delete来释放不是new分配的内存:new分配的内存一定要由delete释放,而delete只能释放new分配的内存。
  • 不要使用delete释放已经释放的内存,这样做的结果将是不确定的
  • 如果使用new [ ]为数组分配内存,则应该使用delete [ ]来释放
  • 如果使用new为一个实体分配内存,则应使用delete(无方括号)释放
  • 对空指针应用delete是安全的

1.4 例

1.4.1 copy书本上的代码:动态分配数组

void App(int* & pa, int len);
int main()
{
    
    
	int* ary = NULL, * t;
	int i, n;
	cout << "n=";
	cin >> n;
	App(ary, n);
	for (t=ary; t < ary+n; t++)
	{
    
    
		cout << *t << " ";
	}
	cout << endl;
	for (i = 0; i < n; i++)
	{
    
    
		ary[i] = 10 + i;
	}
	for (i = 0; i < n; i++)
	{
    
    
		cout << ary[i] << " ";
	}
	cout << endl;
	delete[]ary;
	ary = NULL;
 }
void App(int * & pa,int len)//这里pa的参数类型需是指针引用参数
{
    
    
	pa = new int[len];
	if (pa==NULL)
	{
    
    
		cout << "allocation faiure\n";
		return;
	}
	for (int i = 0; i < len; i++)
	{
    
    
		pa[i] = 0;
	}
}

分析:

  • 动态分配的数组可以使用下标访问,也可以使用指针访问
  • 动态分配数组的格式:类型 * pointer = new 类型[数组长度]
  • 释放动态数组:delete [ ]指针
  • 为了防止内存泄漏,使用指针访问时将ary的值赋给t,否则最后delete掉的不是指向new出来的动态数组
  • App函数中pa使用指针引用参数,如果不用引用参数,ary只是将它的值传给pa,即pa=NULL,但是pa接受到的动态数组的地址不能传给ary,当App调用完之后,pa就会被系统释放(可以将其理解为 一个局部变量)。结果就是ary的值仍然是NULL,而new出来的动态数组无法被delete掉,因为pa已经被被系统释放。如果不用引用参数,App()函数需返回动态数组的指针给ary。

1.4.2 copy书本代码:基本类型

int main()
{
    
    
	int* p = NULL;
	p = new int(100);
	if (p==NULL)
	{
    
    
		cout << "allocation faiure\n";
	}
	else
	{
    
    
		cout << *p << endl;
		delete p;
		p = NULL;
	}
 }

分析:

  • 基本类型使用new申请空间:类型 * 指针变量名 = new 类型(初始值)
  • 可以使用括号初始化申请内存的值
  • delete完之后,指针变量并没有消失,此时将其赋NULL,清除原来的地址值,以免二次释放内存

猜你喜欢

转载自blog.csdn.net/qq_36439722/article/details/105758683