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

一、"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 的场合。

时间: 2016-05-24

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

C++二维指针动态分配内存连续问题

当我们定义一个二维指针时,如果需要存储相应的数据,就需要我们动态的分配内存,这时,有一点是需 要注意的,分配内存的方法不同,内存的连续性也是不相同的,首先,博主先贴出测试代码: #include <cstdlib> #include <iostream> using namespace std; #define nWidth 3 #define nHeight 4 //内存是否连续分配问题 int main(int argc, char *argv[]) { int **p = N

C语言中的指针和内存泄漏

引言 对于任何使用C语言的人,如果问他们C语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但是一旦您了解了指针及其关联内存操作的基础,它们就是您在 C 语言中拥有的最强大工具. 本文将与您分享开发人员在开始使用指针来编程前应该知道的秘密.本文内容包括: 导致内存破坏的指针操作类型 在使用动态内存分配时必须考虑的检查点 导致内存泄漏的场景 如果您预先知道什么地方可能出错,那么您就能够小心避免陷

在使用malloc函数给指针分配内存之后为什么使用编译器打印不出地址。代码如下,编译器为vs2015

问题描述 在使用malloc函数给指针分配内存之后为什么使用编译器打印不出地址.代码如下,编译器为vs2015 #include #include void main() { char *s[10]; int i; for (i = 0;i < 10;i++) { if ((s[i] = (char *)malloc(128)) == NULL) printf("nerrorn"); exit(0); } for (i = 0;i < 10;i++) { printf(&q

了解 C 语言中的指针和内存泄漏及如何避免

如棵你在使用 C 语言时,厌倦花时间调试指针和内存泄漏问题,那么本文将带您了解可能导致内存破坏的指针操作类型,您还将研究一些场景,了解要在使用动态内存分配时考虑什么问题. 引言 对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但是一旦您了解了指针及其关联内存操作的基础,它们就是您在 C 语言中拥有的最强大工具. 本文将与您分享开发人员在开始使用指针

二维指针动态分配内存连续问题深入分析

当我们定义一个二维指针时,如果需要存储相应的数据,就需要我们动态的分配内存,这时,有一点是需要注意的,分配内存的方法不同,内存的连续性也是不相同的   首先,小编先贴出测试代码: 复制代码 代码如下: #include <cstdlib> #include <iostream> using namespace std; #define nWidth  3 #define nHeight 4 //内存是否连续分配问题 int main(int argc, char *argv[])

指针-关于内存分配的问题

问题描述 关于内存分配的问题 关于内存分配,结构体定义式多定义了一个指针的情况typedef struct node{ int a; int b;}Node *ANode;那么为变量Node P 和 为变量 ANode Q创建空间P=(Node *)malloc(sizeof(Node)):和 Q=(ANode)malloc(sizeof(ANode)):区别在哪里 解决方案 Node P ---这个定义 的节点对象实例和 为变量 ANode Q ---这个定义了一个指向对象实例的指针创建空间P

释放指针对象内存-QList中的指针成员无法释放内存,大家是怎么做的?

问题描述 QList中的指针成员无法释放内存,大家是怎么做的? QThread * thread = new QThread(); QList * list = new QList(); list->append(thread); 然后遍历QList中的线程,当某个线程运行完后释放内存 delete list->takeAt(i); 但发现程序运行很久后占用的内存在增大,是不是delete list->takeAt(i);没有释放掉内存 解决方案 加一句list->takeAt(i

二维指针动态分配内存连续问题深入分析_C 语言

首先,小编先贴出测试代码: 复制代码 代码如下: #include <cstdlib>#include <iostream>using namespace std;#define nWidth  3#define nHeight 4//内存是否连续分配问题 int main(int argc, char *argv[]){    int **p = NULL;    p = (int**)malloc(nWidth*sizeof(int*));    if(p == NULL)  

C++中给二维指针分配内存(实现代码)_C 语言

原理就不写在这里了,毕竟网上的介绍有很多,代码如下所示: 复制代码 代码如下: #include <iostream>using namespace std; #define  N  5#define  M  10 int main(int argc, char **argv){ int **p; int i,j;  p = new int* [N]; for (i = 0; i < N; i++)  p[i] = new int [M];  for (i = 0; i < N;