C/C++指针内存分配小细节

摘要:
newchar[n]中的n指定分配给指针变量的内存空间。事实上,上述程序是正确编译和运行的。1BYTE内存空间将自动分配。给p[1]赋值不会报告错误,但释放内存空间会报告错误,因为编译器并没有真正将内存分配给内部指针变量,这就像成功分配内存的指针变量,char*pc=NULL;这意味着将五个BYTE内存空间分配给指针变量(因为类型是char),并且delete必须出现在new之后。

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++指针内存分配小细节》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ubuntu mysql允许root用户远程登录罗素-我为什么而活(中英文)What I have Lived For——Bertrand Russell下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java在一台电脑上装两个或多个jdk如何配置环境变量,并实现jdk切换

前言 在我们学习或者工作的时候可能根据项目的需求需要使用不同的jdk,那么如何在一台电脑上实现多个jdk的配置同时方便切换呢? 一、前期准备 我这里用两个jdk来给大家演示,分别是jdk8和jdk14。首先去官网下载所需要jdk的安装包,或者压缩包。 二、安装 下载完成后,安装或者解压到你认为合适的位置。 三、注意事项 解压版跳过此项 如果是安装版,请务必...

plsql学习笔记1

declare/*申明区 声明变量 定义类型*/ beginplsql的程序结构 /*执行区 执行sql语句或者plsql语句*/ exception/*异常处理区*/ end; set severoutput on 将输出结果显示在屏幕上 ---------------------------------------- 变量的数据类型标准类型:numbe...

Java虚拟机:十八、Java对象大小、对象内存布局及锁状态变化

一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法。不过还好,在JDK1.5之后引入了Instrumentation类,这个类提供了计算对象内存占用量的方法。至于具体Instrumentation类怎么用就不说了,可以参看这篇文章如何精确地测量java对象的大小。 不过有一点不同的...

深入理解JavaScript闭包

一、变量的作用域   要理解闭包,首先必须理解Javascript特殊的变量作用域。变量的作用域无非就是两种:全局变量和局部变量。Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。另一方面,在函数外部自然无法读取函数内的局部变量。(这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全...

丝杠推力计算器

背景来由 为什么会做这个丝杠推力计算器呢。 首先因为目前的工作需要经常做丝杠和电机匹配的选型,手工计算丝杠推力个人觉得还是比较麻烦的,一个公式需要翻来覆去的变换才能计算不同的变量值。 再有 WIN 10 提供的计算器科学模式居然没有 pi 值,计算起来非常不方便,而且结果不能保存相互对比,所以就有了这个丝杠推力计算器。 简单介绍 丝杠推力计算器可以任意计算...

windows环境中Tomcat实现开机自启动

一:安装jdk和tomcat (以64位为示例) 1.jdk安装: 下载:https://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html 选择对应版本进行下载,然后进行安装。 2.tomcat安装: 下载:http://tomcat.ap...