2013-08-19 63 views
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; 
+5

你为什么认为它会给这个结果? – Borgleader

+0

您正在索引空指针。如果你想给每个元素赋0,使用'std :: fill(_n)'。 – chris

+1

你只是改变指针指向的东西。首先,它指向一个数组,然后它指向无处。没有什么指向阵列了。 – juanchopanza

回答

7

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

double * a = 0; //or NULL 

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

+0

我想我明白我无法访问任何东西NULL指针**,即使我之前分配的内存没有被销毁**。谢谢 – SAAD

1

将零赋值给一个指针不会破坏已分配的内存,该指针将指向该内存段。分配零后,delete[]不会删除该部分内存。

2

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

在你的代码中,a是一个指向你自己使用的内存区域的指针(使用new)。所以你有一个值a0x05237484(只是一个随机的例子)。所以,你知道通过这个地址0x05237484有24个字节(3 * 8,8是一个双倍的大小)为你保留的字节。 从本质上讲,当你说new double[5]时,你对运行时所说的是: “现在,找到一个足够空间来存储5个双打数组,并为我保留它,所以只有我可以使用它”。运行时为您预留内存并将地址存储在您提供的指针中 - a

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

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

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

你不会知道在那个位置是什么 - 但尝试它,你要么打“拒绝访问”错误,或者收到的随机数据(属于应用程序的其他部分)。

而且,更糟糕的是,你已经记住了一些内存给你,但没有释放它 - 这意味着你已经从计算机内存中吃掉了没有。这就是所谓的'内存泄漏'

+0

不,它不应该崩溃 - 它只是泄漏内存。定义一个NULL指针的'delete'是安全的。设置'a = 17;'会导致未定义的行为(潜在的崩溃)。用空指针删除 –

+3

- 是的,但是阅读怎么样? “访问冲突 - 从地址0x000000读取”是在Win98天后的相当频繁的错误:) – DarkWanderer

+0

啊,对不起,我同意。 –