为指针赋值是否会破坏分配的内存?

时间:2013-08-19 11:49:44

标签: c++ pointers memory-management

我的问题对某些人来说似乎微不足道,但我不明白为什么这段代码:

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;

3 个答案:

答案 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。这意味着内存仍然为您保留(因为您没有告诉运行时您不再需要它,使用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

您不会知道该位置的内容 - 但是尝试它,您可能会遇到“拒绝访问”错误,或者收到一些随机数据(属于应用程序的其他部分)。

而且,为了让事情变得更糟,你已经给了你一些记忆但却没有释放它 - 这意味着你已经从你的计算机RAM中吃掉了什么。这就是所谓的“内存泄漏”

答案 2 :(得分:1)

为指针指定零不会破坏已分配的内存,该指针会指向该内存段。分配零后,delete[]将不会删除该部分内存。