Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;删除指针(释放内存)_C++_Pointers_Memory Management - Fatal编程技术网

C++ C++;删除指针(释放内存)

C++ C++;删除指针(释放内存),c++,pointers,memory-management,C++,Pointers,Memory Management,考虑以下代码: int a = 10; int * b = &a; int * c = b; delete b; // equivalent to delete c; 我在最后一行中理解的正确吗?delete b和delete c是等效的,两者都将释放a的内存空间,因此a不再可访问?程序的行为未定义。只能对使用new分配的内存指针使用delete。如果你写过 int* b = new int; *b = 10; int* c = b; 然后您可以编写deleteb或删除c以释放内存。

考虑以下代码:

int a = 10;
int * b = &a;
int * c = b;
delete b; // equivalent to delete c;

我在最后一行中理解的正确吗?
delete b
delete c
是等效的,两者都将释放
a
的内存空间,因此
a
不再可访问?

程序的行为未定义。只能对使用
new
分配的内存指针使用
delete
。如果你写过

int* b = new int;
*b = 10;
int* c = b;

然后您可以编写
deleteb
删除c以释放内存。在调用
delete
后,不要尝试取消引用
b
c
,但这样做的行为也未定义。

如果
b
c
指向相同的内存,则删除它们中的任何一个都会释放内存,因此假设是正确的<在这种情况下,代码>变得不可访问是不正确的,因为您没有指向动态分配的内存,并且只能对使用
新建
/
新建[]
创建的内容调用
删除
/
删除[]
。试图
delete
/
delete[]
未分配
new
/
new[]
的指针是未定义的行为,通常会以分段错误结束。

令人困惑的是,问题的答案是

我在最后一行的理解正确吗?删除b和删除c是等效的“


是的,它们是等价的,并且都是UB,正如这里其他地方提到的。

您不应该对堆栈上分配的变量使用delete, delete是new的对应项。
因此,当不使用新的/分配时,不需要删除/释放,一旦您超出代码的“范围”(在本例中为程序本身),所有内存都被视为可用。

a
未被动态分配,因此对其使用
delete
会导致未定义的行为。

(a是在堆栈上创建的,不需要删除它。如果我们忽略堆栈对象的
delete
,如果
b
指向一个
new
分配的对象,那么
delete
ing
c
b
将是等效的:两者都指向相同的
delete
d,您是正确的object@AndrewHenl但不必是SigSeV.C++中没有删除指针。删除了用“代码>新< /代码>分配的对象。不要说“堆栈”——这不是语言概念。使用术语“自动存储持续时间”。相反,它是由C++标准定义的。而且,您也从错误的角度来对待它。对于静态存储时间变量(例如全局变量)使用DELIST也是错误的。。您可以更精确地说明应该执行的操作:仅对
new
返回的指针使用
delete
。甚至对
new[]返回的指针也不使用
delete
。这也是原始指针如此危险的原因。无法知道某个指针指向的动态分配内存是否被指向同一内存的另一个指针删除。并尝试“检查”通过取消引用会导致未定义的行为。@GillBates这就是为什么原始拥有指针是危险的。非拥有指针是可以的。@NathanOliver如果你不使用智能指针并且你
新的
东西,那么你将拥有拥有的指针。我们在这里还没有谈到智能指针,所以我不打算在这里提起它当谈到原始指针的危险时。我不这么认为。为了有一个弱指针,你需要在某个地方有一个共享指针,所以现在你有了原子引用计数。如果我只想从容器返回一个元素,如果它不存在,我想返回
null
,那么原始指针就可以了。智能指针有到处放置但智能指针不是必需的IMHO。在不存在的情况下,如果它绝对必须是一个指针,我更喜欢按照
std::optional
返回一些东西。这实现了相同的目标,但使界面更具表现力。用户忘记或忽略了“空”返回值的可能性要小得多。嗯,这似乎是一个哲学问题的开始。编译器不需要以同样的方式处理
delete b
delete c
,因为如果它看到其中任何一个,它应该做什么都没有任何要求。因此,要确定它们是否“等效”,我们必须决定什么是“等价物”意思是…@greatduck我一般说,但不总是这样。首先,它是未定义的行为。不管发生什么都不重要。@greatduck是一个稻草人。UB并不意味着代码将格式化你的硬盘。@greatduck我不喜欢例外。相反,我更喜欢封装,在我需要时使用智能指针需要拥有指针。这样就不必担心,也不会有异常开销,除非有新的抛出,但在这一点上真的没有什么可做的。@greatduck是否可以将其视为GC,是的。是吗,这取决于。如果使用a,它的开销不会比使用原始
new
delete
的开销大,但除非您尝试破坏它,否则它是100%安全的。a
shared_ptr
更像GC,因为它有一个引用计数,但它是细粒度的,因为它只适用于指针,而不适用于代码中的任何其他内容。