C++随记(二)---动态分配内存问题(1)

C++随记(二)---动态分配内存问题(1)

面向对象的编程的一个特点就是在运行阶段(而不是编译阶段)进行决策。运行阶段决策提供了灵活性,可以根据当时的情况进行调整。具有代表性的就是,可以在运行阶段分配内存。

C语言使用库函数malloc()来分配内存;C++中可以这么用,但是更为常用的就是用new运算符来分配内存,在了解new运算符时你最好已经知道C++的指针是怎么回事。

1、new的简单使用

先来看一个简单的例子:

例如通常情况下,我们需要创建一个指向int类型的指针,程序就会如下:

int a =1;

int *point = &a;

这样,在程序的编译阶段,int变量a的地址就会赋值给int类型的指针point。

如果,在程序运行阶段,为一个int值分配未命名的内存,程序就会如下:

int* point2 = new int;

等号左边表示我定义了一个指向int类型的指针,等号右边,我用运算符new开辟一个可以存储int类型数据的内存区域(因为不同类型的变量需要占用的内存不同),返回此区域的地址。

通过上面那行程序,我就得到了一个内存块,但是我并不知道此内存块的名字,因为我没有给它命名,但是,我知道这片儿区域的地址,point2. 如果我需要取得这个内存块中存储的值,可以用 *point2 , 这就相当于是一个int变量了

举一个通俗的例子来描述上述过程,比如我们通常都不知道我们寝室叫什么名字,因为通常我们不会给寝室取名字,开学的时候,我们去报道,首先明确类型,我是本科生,学校就分给我一个本科生的宿舍(4人间),然后返回此寝室的地址,比如1栋101:1101.然后以后要找我们寝室这四个人,都是直接说1101寝室的同学。

使用new开辟内存之后,你要记得最后要用delete来释放内存,比如你毕业了,就得卷铺盖卷从寝室搬出去,1101的四位同学都搬出寝室。否则将会发生内存泄漏(memory leak),就是说被分配的内存再也无法使用,1101的人不搬走,其他同学当然用不成这个寝室了。

类型名* point2 = new 类型名;

···;

Delete point2;

2、使用new来创建动态数组

对于大型数据,如数组、字符串、结构体,使用new才能真正体会到动态开辟内存的妙处。熟悉数组的朋友应该还记得,创建数组时,一定要明确数组的大小,否则无法成功创建,意味着数组是在编译的时候加入到程序中的,这叫做 静态联编。

而使用new时,我在程序运行时将视具体情况来决定我是否创建数组,并且可以选择其长度,这样的数字称之为 动态数组,此过程被成为 动态联编。 示例: int * points = new int[5]; delete [ ] points;//注意此处一定要有方框[ ],表示我释放的是这整个数组。 使用new和delete时的注意要点: New和delete应该成对出现; 不要用delete来释放不是new开辟的内存; `不要用delete释放同一个内存块两次; `如果用new[ ]为数组分配内存,一定要用delete[ ]来释放内存; `对空指针使用delete是安全的。

3、使用动态数组

int * points = new int[5]; 对于这样一个数组,points指向的是第一个元素的地址,如果要访问第一个元素,那么就可以直接*points。 那么如何访问第二个,第三个元素呢? 把points看成是一个数组!points[1]就是第二个元素,points[0]就是第一个元素,这是因为C++内部也使用指针来处理数组。详细分析会在下一篇博文介绍。 这里先提出一个和数组不一样的地方,对于本例的points来说,points+1后,这个地址对应的就是第二个元素了,points+2对应的就是第三个元素了,这样的加减是合法的。而且加减是以points 对应的类型 所占的字节数 为步长的,即points+1不是说地址的数值只加1,而是加了一个int的长度。 但是如果一个数组int Array[5],我们是不能对数组名Array进行加减的!即Array+1是非法的!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

深入 Python 字典的内部实现

字典是通过键(key)索引的,因此,字典也可视作彼此关联的两个数组。下面我们尝试向字典中添加3个键/值(key/value)对: 这些值可通过如下方法访问: 由...

34615
来自专栏编程

让你比95%的人更懂Pythonic的内置模块:collections

Python的集合(collections)模块,为很多用其他方法很难实现的场景提供了解决方案。 本文我们将会学习该模块的抽象概念是如何产生的,日后处理不同问题...

1915
来自专栏微信公众号:Java团长

探秘Java中的String、StringBuilder以及StringBuffer

  相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String、StringBuilde...

732
来自专栏小俊博客

Nginx的location规则迷之匹配

Nginx,一个改变世界的软件,其作者是一个俄罗斯人,俗称毛子,在国人的印象中,是一群晚饭后牵着大灰熊在小区楼下散步的彪汉。能写出这般顺滑的软件,可谓是心有猛虎...

4492
来自专栏coding for love

JS入门难点解析3-作用域

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

752
来自专栏微信公众号:Java团长

Java集合框架综述

最近打算复习复习JDK中的集合框架,并尝试分析其源码,这么做一方面是这些类非常实用,掌握其实现能更好的优化我们的程序;另一方面是学习借鉴JDK是如何实现了这么一...

873
来自专栏PHP实战技术

你真的懂let和const吗?

在ES6之前我们脑海里应该只存在全局作用域和函数级作用域,没有块级作用域。那么为什么要引入块级作用域呢?

40611
来自专栏拭心的安卓进阶之路

Java 集合深入理解(3):Collection

今天心情有点粉,来学学 Collection 吧! 什么是集合? 集合,或者叫容器,是一个包含多个元素的对象; 集合可以对数据进行存储,检索,操作; 它们可以...

2185
来自专栏程序员互动联盟

【专业技术】C++里面重要的几个关键字的用法

编者按: 这几个关键字非常重要,程序中经常见到他们的身影,但是确切意思有时候还需要多搜索下才能知道。笔者这里把它搬出来,也是希望大家引起重视,努力掌握它。 C+...

3587
来自专栏Java架构沉思录

你真的懂Java中的String、StringBuilder和StringBuffer吗?

相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String、StringBui...

1363

扫码关注云+社区