0

对于某些人来说,我的问题可能看起来微不足道,但我不明白为什么这段代码:

double * a = new double [3];
a[0] = 1;
a[1] = 2;
a[2] = 3;

a = 0;

for(int i=0; i<3;i++)
cout << " a[" << i << "] = " << a[i] << endl;

delete [] a ; 

没有给出以下结果:

a[0] = 0;
a[1] = 0;
a[2] = 0;
4

3 回答 3

7

分配的原始内存new[]泄漏。你现在有相当于

double * a = 0; //or NULL

与内存泄漏。访问空指针会给你未定义的行为。不,分配0给指针不会破坏内存。

于 2013-08-19T11:51:47.457 回答
2

您的代码将崩溃和/或产生一些随机结果(如果您将其他常量分配给a)。为什么?

在您的代码中,a是指向内存的某个区域的指针,您声称该区域供您自己使用(使用new)。所以你有一个alike的值0x05237484(只是一个随机的例子)。因此,您知道该地址0x05237484为您保留了 24 个字节(3*8,8 是双精度数的大小)字节。本质上,当您说 时new double[5],您对运行时说的是:“现在,给我找一个足够存储 5 个双精度数组的空间,并为我保留它,所以只有我可以使用它”。运行时为您保留内存并将地址存储在您提供的指针中 -a

然后,您所做的是a用其他值覆盖指针。delete这意味着内存仍然为您保留(因为您没有通过使用or告诉运行时您不再需要它delete[]),但是您忘记了它的存储位置。

相反,您的记录现在指向其他一些内存位置——那里可能有任何东西。所以,要么你会从你现在指向的地方得到一些随机值(如果你碰巧在同一个进程内存中结束),要么你的程序会崩溃,说“访问冲突”——这意味着你试图访问属于另一个进程/系统/其他。分配后您在这里所做a = 0的是访问 3 个位置:

a[0] // which is a+0 == 0x00000000
a[1] // which is a+1 == 0x00000001
a[2] // which is a+2 == 0x00000002

你不会知道那个位置有什么——但是尝试一下,你要么会遇到“拒绝访问”错误,要么会收到一些随机数据(属于应用程序的其他部分)。

而且,更糟糕的是,您已经占用了一些内存但没有释放它 - 这意味着您已经白白消耗了计算机 RAM。这就是所谓的“内存泄漏”

于 2013-08-19T12:03:45.353 回答
1

将零分配给指针不会破坏分配的内存,该指针停止指向该内存段。并且赋值为零后,delete[]不会删除那部分内存。

于 2013-08-19T11:55:46.367 回答