我的问题对某些人来说似乎微不足道,但我不明白为什么这段代码:
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;
答案 0 :(得分:7)
分配了new[]
的原始内存被泄露。你现在有相当于
double * a = 0; //or NULL
内存泄漏。访问空指针将为您提供未定义的行为。不,将0
分配给指针不会破坏内存。
答案 1 :(得分:2)
您的代码将崩溃和/或产生一些随机结果(如果您将一些其他常量分配给a
)。
为什么呢?
在您的代码中,a
是指向内存某些区域的指针,您声称自己使用(使用new
)。因此,您的a
值为0x05237484
(仅为随机示例)。所以,你知道通过那个地址0x05237484
有24个字节(3 * 8,8是双倍的大小)为你保留的字节。
基本上,当你说new double[5]
时,你对运行时说的是:
“现在,给我一个足够的空间来存储5个双打的数组,并为我保留,所以只有我可以使用它”。运行时为您保留内存并将地址存储在您提供的指针中 - a
然后,你要做的是用其他值覆盖指针a
。这意味着内存仍然为您保留(因为您没有告诉运行时您不再需要它,使用delete
或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中吃掉了什么。这就是所谓的“内存泄漏”
答案 2 :(得分:1)
为指针指定零不会破坏已分配的内存,该指针会指向该内存段。分配零后,delete[]
将不会删除该部分内存。