关于指针和内存的几个问题
当前位置:以往代写 > C/C++ 教程 >关于指针和内存的几个问题
2019-06-13

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

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

副标题#e#

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


#p#副标题#e#

八、该怎麽用 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:",假如你想要有衍生类此外话)。

#p#分页标题#e#

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;
}

    关键字:

在线提交作业