加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

EasyC++16,指针初探之二

发布时间:2021-11-04 05:31:02 所属栏目:语言 来源:互联网
导读:大家好,我是梁唐。 想要追求更好阅读体验的同学,可以点击文末的「阅读原文」,访问github仓库。 危险的case 指针由于能够操作内存,所以如果使用的时候不够仔细,很容易引发一些意想不到的错误。 C++ Primer当中给了这样一个例子: int *ptr; *ptr = 2333;
大家好,我是梁唐。   想要追求更好阅读体验的同学,可以点击文末的「阅读原文」,访问github仓库。   危险的case 指针由于能够操作内存,所以如果使用的时候不够仔细,很容易引发一些意想不到的错误。   C++ Primer当中给了这样一个例子:   int *ptr;  *ptr = 2333;  在这段代码当中我们声明了一个int型的指针,并且将它指向了2333。然而,这里有一个问题,我们在声明指针的时候并没有进行初始化。没有初始化的指针并不为空,而是指向一个未知的地方。如果说它指向的是一个常量1200的地址,我们让它等于2333,那么之后当我们使用1200这个常量的时候,得到的结果都是2333。   更可怕的是,整个过程非常地隐蔽,很难察觉。debug的时候会令人抓狂。   所以千万不要修改一个没有初始化的指针指向的值。   指针和数字 C++ Primer当中还给了另外一个例子,当我们输出指针的时候,得到的是一串十六进制的数。那我们能不能反过来将一个十六进制的数赋值给指针呢?   int *p;  p = 0xB8000000;  答案是不行,因为类型不一致。虽然我们打印指针的时候看起来得到是十六进制数,但它的类型其实是指针类型,而不是整数类型。所以我们将一个整数赋值给一个指针是不行的,如果非要赋值,必须要进行类型转换。   int *p;  p = (int*) 0xB8000000;  但是这一转换之后显然又出现了一个问题,我们知道0xB8000000这个地址指向哪里么?显然不知道,自然也就说不清改了这里的值之后会引发什么结果。   所以虽然这么做可行,但也强烈不建议这样干。   new操作 前文说过使用指针有一个非常大的好处就是可以在程序运行的时候,动态分配内存。其实在C语言当中也有类似的功能,可以使用malloc来分配内存。不过在C++当中有了更好用的运算符——new。   比如我们要动态创建一个int类型的变量,可以这样写:   int *ptr = new int;  new运算符根据之后的类型确定需要的内存大小,找到这样的内存之后,返回地址。刚好指针接收的值就是内存地址,因此刚好可以完成这样的赋值操作。   上面的代码也可以写成这样:   int a;  int *ptr = &a;  这两者有什么区别呢?表面上看没有区别,都是创建了一个int类型的变量。只不过第二种写法除了可以使用指针ptr之外,还可以使用变量名a来访问这个int。   但实际上这两者的内部实现完全不同,我们直接通过变量名创建的变量它的值会被存储在栈内存当中,而通过new创建的对象则被存储在堆内存当中。栈内存是由系统自动分配,而堆内存则是由程序员进行申请使用。这两者的内存模型是完全不同的,我们会在之后的文章详细地讨论这点。目前简单来理解的话,就是堆内存更加灵活,它的空间也更大,可以存储下更大的数据。   delete操作 有了动态创建,自然也就有动态删除,所以C++当中有一个delete操作和new相对应。   delete运算符可以在变量使用结束之后,将内存归还给内存池。因为很多时候程序当中的变量都是一次性使用或者是有生命周期的,当生命周期结束,使命完成就没有必要继续占用着资源了。毕竟系统内的内存资源是有限的,尤其是在一些大型项目或者嵌入式系统当中,内存资源非常紧张。   delete运算符之后跟一个指针,它会释放改指针指向的内存。   int *ptr = new int;  delete ptr;  这里面有很多坑,千万要当心。首先是使用了new创建了内存之后,一定要记得delete,否则这块内存将会永远被占用无法得到释放,这种情况被称为内存泄漏(memory leak)。另外,我们不能delete一个已经delete过的指针,这也会引发严重错误。C++ Primer对此的描述是:什么情况都可能发生。当然也不能再使用一个已经被delete的指针,这会引发空指针错误。   指针对于C++来说是一把双刃剑,像是Java、Python、Go等其他语言,内存回收的工作都是由系统自动执行的。例如Java的JVM虚拟机设计了严密的GC(垃圾回收)机制,程序员无须关心内存的回收问题,全部交给程序自动完成。   而在C++当中,这一过程是由程序员手动执行的,某种程度上来说,这当然非常好,程序员拥有了很高的权限以及灵活度。但同样也是一个坑,尤其是在复杂系统当中,很难准确判断delete执行的时间。这会引发严重的问题,例如内存泄漏严重,野指针到处飞等……

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!