C++ 给指针赋值零会破坏分配的内存吗?

C++ 给指针赋值零会破坏分配的内存吗?,c++,pointers,memory-management,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 ; 使用new[]分配的原始内存泄漏。你现在有了相当于 do

对于某些人来说,我的问题似乎微不足道,但我不明白为什么会出现以下代码:

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 ; 

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

double * a = 0; //or NULL

内存泄漏。访问空指针将导致未定义的行为。不,为指针赋值
0
不会破坏内存。

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

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

在您的代码中,
a
是指向内存中某个区域的指针,您声明该区域供自己使用(使用
new
)。所以你有一个
a
的值,比如
0x05237484
(只是一个随机的例子)。因此,您知道,通过该地址
0x05237484
为您保留了24个字节(3*8,8是双精度的大小)。 本质上,当您说
newdouble[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
您不知道那个位置有什么,但尝试一下,您要么会遇到“拒绝访问”错误,要么会收到一些随机数据(属于应用程序的其他部分)


而且,更糟糕的是,你拿走了一些内存,但没有释放出来——这意味着你白白吃掉了计算机内存。这就是所谓的“内存泄漏”

为什么您认为它会给出这个结果?您正在索引一个空指针。如果要为每个元素指定0,请使用
std::fill(\n)
。您只需更改指针指向的对象。首先,它指向一个数组,然后它不指向任何地方。而且再也没有东西指向数组了。@Borgeader我想如果我指向0,那么我显然会“取消”分配空间中的任何值。。。但现在我明白为什么它不工作了不,它不应该崩溃-它只是泄漏内存<带有空指针的代码>删除定义为安全。设置
a=17将导致未定义的行为(潜在崩溃)。使用空指针删除-是,但如何读取?“访问冲突-读取地址0x000000”在Win98的日子里是一个非常常见的错误:)啊,对不起,是的,我同意。我想我明白,我不能访问空指针之后的任何内容,即使我以前分配的内存没有被破坏。谢谢
a[0] // which is a+0 == 0x00000000
a[1] // which is a+1 == 0x00000001
a[2] // which is a+2 == 0x00000002