C/C++指针内存分配小细节
char *pc = NULL;
pc = new char[0];
pc[0] = '1';
相信初学者看见上面这段代码,都会觉得奇怪,new char[n]中的n指定给指针变量分配多少内存空间,而n=0时代表什么呢?
其实上面的程序编译、运行都是正确的。因为编译器识别到指定大小为0时,会自动为其分配1BYTE的内存空间。
尝试过的小伙伴会发现,给p[1]赋值也不会报错,原因留到后面讲*1。
但是,此时若想用delete [] p; 去释放内存空间就会报错,程序强制中断,因为编译器并没有真正意义上内指针变量分配内存,去释放肯定是不行的。
这就像对一个成功分配内存的指针变量,连续释放两次造成的错误,例子见后面*2。
好了,马上看一下成功分配内存的情况是怎么样的。
char *pc = NULL;
pc = new char[5];
pc[0] = '1';
这里的n=5,意味着给指针变量分配5个BYTE内存空间(因类型为char),当然不管是什么类型,指针变量本身均占4BYTE。
先来看上面遗留的第一个问题*1:此时不但可以给p[0]到p[4]赋值,还可以给后面的地址赋值,如p[5],p[10]等。
这就是C/C++完美之余的一个历史遗留缺陷,不进行越界检查。
导致编译没有任何问题,运行阶段有时一不小心也察觉不出,这就要求程序员养成良好的习惯:new后面必出现delete。
若我们在给p[5]或之后的地址赋过值,在运行到delete [] p;语句时,会报错,程序强制中断。错误原因如提示的信息:damage:after normal block。
这就是上面遗留的第二个问题*2:对同一个指针变量指向的内存释放两次,与释放一个没有成功分配内存或引用越界的指针变量类似,都是不允许的。
还有一个值得注意的地方:若new时n>0,delete后只是释放了原来内存地址中对应的值,指针变量仍然指向该内存地址,即:
仍可以赋值、取值进行运算,只是若没有重新赋值,取出的值为不确定值,换句话说就是,p成了传说中的野指针。
所以,这又是一个要求养成良好习惯的地方,看文章开头的地方,声明一个指针但未分配内存空间时,最好将其置为NULL。
这样做有两个好处:1、方便后面进行判断,if(!P){...}表示无内存分配,若当初没有将其置为NULL,则!p为真也代表不了什么;
2、在delete后,重新分配内存之前,将其置回为NULL,避免其成为野指针。
而对于malloc与free,情况类似,有兴趣的小伙伴可以尝试下。
刚开始学习这一块,有哪里不对的地方欢迎大家指出,谢谢!
C/C++指针内存分配小细节的更多相关文章
- 【C/C++学院】0828-数组与指针/内存分配/数据结构数组接口与封装
[送给在路上的程序猿] 对于一个开发人员而言,可以胜任系统中随意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并能够运用到系统中.由此简化系统的开发,是其架构生涯的第一步. ...
- C指针的一些小细节
1 int *c;*c=4-->int *c;int b;c=&b;*c=4; 在使用指针之前,一定要将其初始化,当然,如果是赋予一个地址,就相当于使用的同时就进行了初始化.
- c语言中较常见的由内存分配引起的错误_内存越界_内存未初始化_内存太小_结构体隐含指针
1.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内浅显的例子就不举了,这里举几个比较隐蔽的例子. 1.1结构体成员指针未初始化 struct stude ...
- TCMalloc源码学习(三)(小块内存分配)
线程本地cache 线程本地cache对应的是类 ThreadCache,每一个thread一个实例,初始化代码在static函数CreateCacheIfNecessary中, 在该线程第一次申请内 ...
- C动态内存分配(C与指针实例)
主要初步介绍malloc.free.calloc.realloc的基本.日后会有更详细的内容. malloc.free分别用于动态内存分配和释放. malloc会从内存池里提取一块合适的内存(连续的) ...
- 【嵌入式开发】C语言 内存分配 地址 指针 数组 参数 实例解析
. Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...
- C语言 内存分配 地址 指针 数组 参数 实例解析
. Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...
- <c和指针>学习笔记5动态内存分配和预处理器
1 动态内存 比如声明数组得时候,我们需要提前预估数组长度,分配大了浪费,少了就更不好操作了.从而引入动态分配,需要的时候再分配. (1)malloc和free void *malloc(size_t ...
- 漫步Facebook开源C++库Folly之string类设计(散列、字符串、向量、内存分配、位处理等,小部分是对现有标准库和Boost库功能上的补充,大部分都是基于性能的需求而“重新制造轮子”)
就在近日,Facebook宣布开源了内部使用的C++底层库,总称folly,包括散列.字符串.向量.内存分配.位处理等,以满足大规模高性能的需求. 这里是folly的github地址:https:// ...
随机推荐
- apache CXF wsdl2java工具的使用
cxf的wsdl2java命令和JDK的wsimport命令的区别和使用 JDK提供了一个wsimport.exe的命令,主要是用于将WebService生成客户端代码,然后好调用WebService ...
- 详细的图文教程来实现 eclipse环境下如何配置tomcat,并且把项目部署到Tomcat服务器上
很多初学,尤其自学JavaWeb的朋友首次在eclipse下配置tomcat时,总会有种难下手的感觉,在此,通过图文解说的方法,最直观的向大家演示一遍该配置过程. 第一部分:eclipse环境下如何配 ...
- shell读取文件每一行的方式
1.使用read命令读取一行数据 while read myline do echo "LINE:"$myline done < datafile.txt 2.使用read命 ...
- Maven使用笔记,错误Failure to Transfer后处理
当有未更新成功的项,M3会以后缀为.lastUpdated保存未更新成功的项 执行下面的操作可清楚这些项 Unixfind ~/.m2 -name "*.lastUpdated" ...
- 22 扩展Python - 《Python 核心编程》
- selenium如何解决window安全验证问题
解决办法 IE浏览器: 1.使用autoit,捕捉到控件后,编写au3脚本,生成exe,然后java调用exe au3脚本 Dim $account = "username" Di ...
- [3D跑酷] MissionManager
前言 许久没有更新日志了,之前写了GUIManager,GUIClickEventReceiver还有AudioManager,这次写MissionManager 引用关系 首先看下MissionMa ...
- mybatis order by绑定的参数
<select id = "queryByStartWithOrder" resultType="org.seckill.entity.SuccessKilled& ...
- 当文本溢出包含的元素时加省略号之text-overflow
text-overflow是css3的属性,用来处理文本溢出,默认裁剪处理,text-overflow属性只能用于block和inline-block元素,内联的和box,flex-flow:colu ...
- NSPredicate简单应用
1.筛选纯字符串数组的内容 NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai& ...