动态内存管理---new&delete
动态内存管理
动态对象(堆对象)是程序在执行过程中在动态内存中用new运算符创建的对象。
因为是用户自己用new运算符创建的。因此也要求用户自己用delete运算符释放,即用户必须自己管理动态内存。
计算机内存数据区常有三种分区。即静态数据区、堆区、桟区。
1.程序在编译时就为静态变量和静态对象分配了静态数据存储区。在静态数据区中存储的变量或对象在该程序的整个执行期间都存在。
它们的生命周期贯穿整个程序的执行周期。比方全局变量、static(静态)变量等都是存储在静态数据区。
2.调用函数时。函数内的局部变量和形式參数等将在桟区中分配存储单元。
这部分变量的生命周期与函数的运行时间同样。
当函数运行结束时,存储这些变量的存储单元会被自己主动释放,从而这些变量的生命周期也就结束了。
因为桟区的大小一般非常有限。因此可以同一时候保存在桟区中的变量数量有限。
因为存储在桟区中的变量生命周期短,因此桟区的使用率高非常高,能够不断成为新生成变量的存放空间。
3.当运行new运算符时,系统会自己主动在动态内存空间中分配存储,动态内存位于堆区,它是唯一一个生存期能够由程序猿自己控制的存储空间。
程序在执行时程序猿能够用new申请动态内存空间。但不用时,程序猿必须自己用delete释放这部分空间(释放内存)。
因此,程序在这部分出错的概率极高。
管理动态内存空间的运算符是new和delete。还有new[]与delete[].
C语言中用 malloc()和free()函数申请分配和释放动态内存空间。
C++用new和delete运算符来申请分配和释放动态内存空间。
new运算符能够自己主动计算所申请空间的大小,而malloc()函数则必须由程序猿指出所需申请分配空间的大小。
#include<iostream>
using namespace std; int main()
{
char *p1;
int *p2;
int *p3=new int (14);
int *p4=new int [3]; p1=new char; //new一个整型数。并将该整型数的地址赋值给p1
p2=new int (10);//new一个初值为200的整型数。并将该整型数的地址赋给p2 *p1=97; for(int i=0;i<3;i++)
{
cin>>*(p4+i);
} cout<<*p1<<endl;
cout<<*p2<<endl;
cout<<*p3<<endl; for(int i=0;i<3;i++)
{
cout<<*(p4+i)<<" ";
}
cout<<endl; delete p3;
delete p2;
delete p1;
delete []p4; p1=NULL;
p2=NULL;
p3=NULL;
p4=NULL; system("pause");
return 0;
}
注意:
1.当系统无法满足动态内存分配的请求时他将会返回NULL,所以new运行后必须推断返回的指针值是否为NULL,是则表示动态内存分配不成功。
仅仅有返回值是非NULL时。才可继续运行兴许的操作。
假设对一个未申请成功的指针进行相关的内存操作将可能引起系统崩溃。
2.delete仅仅能用来释放用new申请分配的动态内存空间;反之。new申请的动态内存空间必须用delete来释放。
delete与new必须有相应的关系。
3.delete运行之后,指针所指向的内存空间就被释放了,而指向该动态内存区域的指针变量本身并不会由于delete有不论什么改变。
4.delete之后,不正确指针变量做不论什么处理,就会造成“指针悬挂”;
5.指针变量声明后没有进行初始化就通过它操作内存空间,则可能制造一个“野指针”;
6.关于指针和动态内存要特别注意:
指针消亡了,并不代表它所指向的动态内存会被自己主动释放,自己主动消亡;
动态内存被释放了,并不代表指向该动态内存的指针变量会消亡或自己主动变成NULL。
做到下面几点,能够防止错误的发生:
1.定义指针变量的同一时候初始化。如不初始化就一定要将其设置成NULL。避免该指针指向一个不确定的地方,引发误操作,这是很危急的。
一旦把它置成NULL,误用它就不会造成太大问题;
2.delete指针以后,第一时间将其设置为NULL。即使是一个立即就要消亡的局部指针变量。也可立即将其置成NULL。养成良好的习惯是避免错误的有效方法;
3.当指针指向数组时。一定慎重防止指针越界操作;
4.避免用指针传递桟内存。避免返回一个即将自己主动消亡的局部变量或局部对象的地址。
桟内存中的局部变量和局部对象都不能跨函数生存,要注意它们的生存周期。
注意 delete :
#include<iostream>
using namespace std; int main()
{
int i,*pi1=&i,*pi2=nullptr; double *pd=new double (33),*pd2=pd; int ii=0; //delete i;//错误,i不是一个指针
cout<<ii++<<endl;
//delete pi1;//为定义:pi1指向一个局部变量,未分配动态内存 cout<<ii++<<endl;
delete pi2;//正确:释放一个空指针 cout<<ii++<<endl;
delete pd;//正确 cout<<ii++<<endl;
//delete pd2;//没有定义,:指向的内存已经被释放了 cout<<ii++<<endl; system("pause");
return 0;
}
对于delete i的请求,编译器会生成一个错误信息。由于它知道i不是一个指针。
运行delete pi1和pd2所产生的错误则更具有潜在危害:通常情况下。编译器不能分辨一个指针指向的是静态还有动态分配的对象。同一时候,编译器也不能分辨一个指针所指向的内存是否已经被释放了。
动态内存管理---new&delete的更多相关文章
- C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)
C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存. 运算符new和delete 使用new动态分配和初始化对象 在自由空间分配的内存是无名的 ...
- 深入理解C++ new/delete, new []/delete[]动态内存管理
在C语言中,我们写程序时,总是会有动态开辟内存的需求,每到这个时候我们就会想到用malloc/free 去从堆里面动态申请出来一段内存给我们用.但对这一块申请出来的内存,往往还需要我们对它进行稍许的“ ...
- 动态内存管理详解:malloc/free/new/delete/brk/mmap
c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, calloc/realloc 上述8个函数/操作符是c/c++语言里常用来做动 ...
- 动态内存管理:malloc/free/new/delete/brk/mmap
这是我去腾讯面试的时候遇到的一个问题——malloc()是如何申请内存的? c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, c ...
- C++动态内存管理之shared_ptr、unique_ptr
C++中的动态内存管理是通过new和delete两个操作符来完成的.new操作符,为对象分配内存并调用对象所属类的构造函数,返回一个指向该对象的指针.delete调用时,销毁对象,并释放对象所在的内存 ...
- (原创)动态内存管理练习 C++ std::vector<int> 模拟实现
今天看了primer C++的 “动态内存管理类”章节,里面的例子是模拟实现std::vector<std::string>的功能. 照抄之后发现编译不通过,有个库函数调用错误,就参考着自 ...
- C++程序设计入门 引用和动态内存管理学习
引用: 引用就是另一个变量的别名,通过引用所做的读写操作实际上是作用于原变量上. 由于引用是绑定在一个对象上的,所以定义引用的时候必须初始化. 函数参数:引用传递 1.引用可做函数参数,但调用时只需 ...
- C++中对C的扩展学习新增语法——动态内存管理
1.C语言动态内存管理的缺点: 1.malloc对象的大小需要自己计算. 2.需要手动转换指针类型. 3.C++的对象不适合使用malloc和free. 2.C++中new/delete基本使用: 3 ...
- C++动态内存管理与源码剖析
引言 在本篇文章中,我们主要剖析c++中的动态内存管理,包括malloc.new expression.operator new.array new和allocator内存分配方法以及对应的内存释放方 ...
随机推荐
- Coursera Algorithms Programming Assignment 1: Percolation(100分)
题目来源http://coursera.cs.princeton.edu/algs4/assignments/percolation.html 作业分为两部分:建立模型和仿真实验. 最关键的部分就是建 ...
- 使用 Polyfill 而不再是 bable 来实践js新特性
现状 我们想要用ES6 语法来写 JavaScript.然而由于我们需要兼容老版本的浏览器,那些浏览器不支持 ES6,我们需要解决这个问题. 有一个标准的做法是:写 ES6 代码 → 将所有代码编译成 ...
- nodejs windows环境安装
相信对于很多关注javascript发展的同学来说,nodejs已经不是一个陌生的词眼.有关nodejs的相关资料网上已经铺天盖地.由于它的高并发特性,造就了其特殊的应用地位. 国内目前关注最高,维护 ...
- 洛谷P2756 飞行员配对方案问题(二分图匹配)
P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其 ...
- Django day13 form组件, 渲染错误信息, 全局钩子
一:from组件 二:渲染错误信息 三:全局钩子
- Angular 显示英雄列表
在本页面,你将扩展<英雄指南>应用,让它显示一个英雄列表, 并允许用户选择一个英雄,查看该英雄的详细信息. 创建模拟(mock)英雄数据 你需要一些英雄数据以供显示. 最终,你会从远端的数 ...
- BZOJ 4488/4052 gcd
思路: 一开始 我是想 对于固定的左端点 从左到右 最多有 log种取值 且单调递减 那不妨倍增预处理+二分GCD在哪变了.. 复杂度O(nlog^2n) gcd最多log种取值.. 好了我们可以 ...
- sql 改字段名
sp_rename '[zErpMini].[dbo].[STK_Stock].Isextension','IsExtened'
- windows phone传感器
Windows phone中的传感器主要包括加速计传感器.罗盘传感器.陀螺仪传感器等 加速计传感器 Accelerometer类是加速传感器的接口,Accelerometer类位于Windows.De ...
- DHCP 和 MDT 分开服务器的设置方法
DHCP设置 043:供应商特定信息:01 04 00 00 00 00 FF 060:PXEClient:PXEClient 066:启动服务器主机名:IP 067:启动文件名:\Boot\x86\ ...