我想问一下,是否动态创建指针,然后将指针地址更改为仍然删除原始分配空间的其他内容?
例如:
int main()
{
int c = 50;
// Memory leak
int * q = new int;
q = & c;
delete q;
}
究竟是删除或发生了什么?
谢谢!
答案 0 :(得分:7)
内存泄漏和未定义的行为。
执行q = & c;
时,您将失去对new int
分配的内存的唯一跟踪。没有人为你追踪这个,没有垃圾收集器,它只是丢失了,无法恢复。
当您执行delete q;
(其中q
分配给&c
)时,您正在删除您未分配的内存,更糟糕的是您正在删除堆栈中的内存。其中任何一个都会导致未定义的行为。
这是一个很好的前言,为什么你应该避免在你不需要它们的情况下使用指针。在这种情况下,没有理由动态分配您的int
。如果您确实需要指针,请使用c++11
智能指针(如果您没有boost
,请使用c++11
)。在极少数情况下,您确实需要原始c
类型指针。您应该阅读Effective Modern c ++第4章,了解有关此主题的详细信息。
答案 1 :(得分:4)
是动态创建指针,然后将指针地址更改为仍然删除原始分配空间的其他内容吗?
否。 delete
将取消分配其操作数指向的内存。您必须delete
从new
获得的同一块内存。
int c = 50;
int * q = new int;
int * r = q;
q = & c;
delete q; // WRONG! q points to something you didn't get from new
delete r; // OK! p points to the block you got from new
更清楚的是,delete
并不关心它操作的变量,它只关心该变量指向的内容。在上面的最后一行中,r
指向q
最初指向并由new
分配的块,因此您可以安全地delete
它。 q
指向静态分配的内存,而不是new
中的内容,因此您无法delete
。
但是,您可以将所需的值复制到q
指向的空间中,而不是更改q
指向的位置:
int c = 50;
int * q = new int;
*q = c;
delete q; // OK! q still points to the same place
您要更改存储在q
指向的位置的值,但您不会更改q
本身。 q
仍然指向您从new
获得的阻止,因此对delete
它是安全的。
答案 2 :(得分:3)
您的代码将(尝试)删除c。在C / C ++中没有内存管理或类似内容。 delete将尝试删除给定指针指向的任何内容,并且任何未删除的内容(通过调用对通过调用new创建的变量的delete,或者通过保留局部变量的范围)将保留在内存中,直到程序结束。
请注意,尝试删除本地变量可能会导致崩溃,因为删除实际上会(以非常基本的方式)检查它删除的内容 - 至少知道在该地址实际分配了多少内存。在此检查中,它将适当地注意到c不包含此信息,或者它甚至不在内存空间的右端,因此它将崩溃。
答案 3 :(得分:1)
它会崩溃,因为在堆栈内存部分中创建了c
。如果你很幸运并且程序没有崩溃,你仍然会泄漏内存,因为q引用丢失了。
答案 4 :(得分:1)
首先回答你的问题: -
我想问一下,是否动态创建指针
我们不会动态创建指针。指针只是一个变量,就像C和C ++中的其他变量一样。区别在于,指针是一个可以存储特定内存位置地址的变量。在运行时,您只需动态分配内存并将该内存大小的第一个地址位置的地址分配给它。
如果您不删除/释放内存并为其分配新地址,将会发生什么。在这种情况下,内存将不会被释放/释放,并且不再可以使用,因为操作系统永远不会将其标记为空闲。当您释放/删除内存O / S时,将该区域标记为可以免费使用,并且您的运行进程可以在将来使用它。这就是调用适当的内存管理。不正确的内存管理会导致程序内存泄漏。