当前位置: 首页 > news >正文

关于指针和内存的几个问题

一、"delete p" 会删去 "p" 指针,还是它指到的资料,"*p" ?

该指针指到的资料。"delete" 真正的意思是:「删去指针指到的东西」(delete the thing pointed to by)。同样的英文误用也发生在 C 语言的「释放」指标所指向的记忆体("free(p)"真正的意思是:"free_the_stuff_pointed_to_by(p)" )。

二、能 "free()" 掉由 "new" 配置到的、"delete" 掉由 "malloc()" 配置到的记忆体吗?

不行。在同一个程式里,使用 malloc/free 及 new/delete 是完全合法、合理、安全的;但 free 掉由 new 配置到的,或 delete 掉由 malloc 配置到的指标则是不合法、不合理的。

三、为什麽该用 "new" 而不是 malloc() ?

建构子/解构子、型别安全性、可被覆盖(overridability)。建构子/解构子:和 "malloc(sizeof(Fred))" 不同,"new Fred()" 还会去呼叫Fred 的建构子。同理,"delete p" 会去呼叫 "*p" 的解构子。
型别安全性:malloc() 会传回一个不具型别安全的 "void*",而 "new Fred()" 则会传回正确型态的指标(一个 "Fred*")。
可被覆盖:"new" 是个可被物件类别覆盖的运算子,而 "malloc" 不是以「各个类别」作为覆盖的基准。

四、为什麽 C++ 不替 "new" 及 "delete" 搭配个 "realloc()" ?

避免你产生意外。当 realloc() 要拷贝配置区时,它做的是「逐位元 bitwise」的拷贝,这会弄坏大
部份的 C++ 物件。不过 C++ 的物件应该可以自我拷贝才对:用它们自己的拷贝建构子或设定运算子。

五、该怎样配置/释放阵列?

用 new[] 和 delete[] :

Fred* p = new Fred[100];
//...
delete [] p;

每当你在 "new" 运算式中用了 "[...]" 的话,你就 *!*必须*!* 在 "delete" 陈述中使用 "[]" 。这语法是必要的,因为「指向单一元素的指标」与「指向一个阵列的指标」在语法上并无法区分开来。

六、万一我忘了将 "[]" 用在 "delete" 由 "new Fred[n]" 配置到的阵列,会发生什麽事?

灾难。这是程式者的--而不是编译器的--责任,去确保 new[] 与 delete[] 的正确配对。若你弄错了,编译器不会产生任何编译期或执行期的错误讯息。堆积(heap)被破坏是最可能的结局,或是更糟的,你的程式会当掉。

七、成员函数做 "delete this" 的动作是合法的(并且是好的)吗?

只要你小心的话就没事。所谓的「小心」是:
1) 你得 100% 确定 "this" 是由 "new" 配置来的(而非 "new[]",亦非自订的 "new" 版本,一定要是最原始的 "new")。
2) 你得 100% 确定该成员函数是此物件最後一个会去呼叫的。
3) 做完自杀的动作 ("delete this;") 後,你不能再去碰 "this" 的物件了,包括资料及运作行为在内。
4) 做完自杀的动作 ("delete this;") 後,你不能再去碰 "this" 指标了。换句话说,你不能查看它、将它与其他指标或是 NULL 相比较、印出其值、对它转型、对它做任何事情。

很自然的,这项警告也适用於:当 "this" 是个指向基底类别的指标,而解构子不是virtual 的场合。

八、该怎麽用 new 来配置多维阵列?

有很多方法,端视你对阵列大小的伸缩性之要求而定。极端一点的情形,如果你在编译期就知道所有阵列的维度,你可以静态地配置(就像 C 一样):

class Fred { /*...*/ };

void manipulateArray()
{
Fred matrix[10][20];

//使用 matrix[i][j]...

//不须特地去释放该阵列
}

另一个极端情况,如果你希望该矩阵的每个小块都能不一样大,你可以在自由记忆体里配置之:

void manipulateArray(unsigned nrows, unsigned ncols[])
//'nrows' 是该阵列之列数。
//所以合法的列数为 (0, nrows-1) 开区间。
//'ncols[r]' 则是 'r' 列的行数 ('r' 值域为 [0..nrows-1])。
{
Fred** matrix = new Fred*[nrows];
for (unsigned r = 0; r < nrows; ++r)
matrix[r] = new Fred[ ncols[r] ];

//使用 matrix[i][j]...

//释放就是配置的作:
for (r = nrows; r > 0; --r)
delete [] matrix[r-1];
delete [] matrix;
}

九、怎样确保某类别的物件都是用 "new" 建立的,而非区域或整体/静态变数?

确定该类别的建构子都是 "private:" 的,并定义个 "friend" 或 "static" 函数,来传回一个指向由 "new" 建造出来的物件(把建构子设成 "protected:",如果你想要有衍生类别的话)。

class Fred { //只允许 Fred 动态配置出来
public:
static Fred* create() { return new Fred(); }
static Fred* create(int i) { return new Fred(i); }
static Fred* create(const Fred& fred) { return new Fred(fred); }
private:
Fred();
Fred(int i);
Fred(const Fred& fred);
virtual ~Fred();
};

main()
{
Fred* p = Fred::create(5);
...
delete p;
}

相关文章:

  • 使用STM32CubeMX配置STM32串口
  • 浅谈C++函数的参数
  • 使用STM32CubeMX新建Keil工程
  • 使用QT新建工程并成功编译
  • 旅游整理
  • 简单几步向Android Studio导入Eclipse工程
  • Xmind免费安装使用教程
  • 今天日志
  • Ubuntu下JetBrains 系列软件的免费安装教程
  • 笑傲江湖与三层交换、路由......
  • 清华镜像源安装tensorflow
  • MSNShell效果,来个养眼的......
  • 清华镜像源安装opencv或opencv-contrib
  • 面向对象技术第一讲 多态性(原创)
  • matlab提取图形形心
  • 分享的文章《人生如棋》
  • 【EOS】Cleos基础
  • 【面试系列】之二:关于js原型
  • Angular 响应式表单之下拉框
  • CSS魔法堂:Absolute Positioning就这个样
  • isset在php5.6-和php7.0+的一些差异
  • Java超时控制的实现
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • mysql中InnoDB引擎中页的概念
  • Next.js之基础概念(二)
  • React系列之 Redux 架构模式
  • uva 10370 Above Average
  • vue:响应原理
  • 从tcpdump抓包看TCP/IP协议
  • 动态魔术使用DBMS_SQL
  • 缓存与缓冲
  • 经典排序算法及其 Java 实现
  • 树莓派 - 使用须知
  • kubernetes资源对象--ingress
  • MPAndroidChart 教程:Y轴 YAxis
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 带你开发类似Pokemon Go的AR游戏
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #NOIP 2014# day.2 T2 寻找道路
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $.ajax中的eval及dataType
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (十八)三元表达式和列表解析
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (算法)N皇后问题
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)iOS字体
  • (转)JAVA中的堆栈
  • (转)Linux下编译安装log4cxx
  • (转)详解PHP处理密码的几种方式
  • (转载)从 Java 代码到 Java 堆
  • .describe() python_Python-Win32com-Excel
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查