【C++学习】谈谈我对C++中delete的看法

前言

delete 用于释放动态申请的内存。

  1. 传递给delete的指针必须指向动态分配的内存,或者是一个空指针
  2. delete一块并非new的内存,或将相同的指针值释放多次,其行为是未定义的。
  3. 编译器不能分辨一个指针所指向的对象是静态还是动态分配的。
  4. 编译器也不能分辨一个指针所指向的内存是否已经释放。
延伸

delete一个已经delete的指针,为什么有时候会报错有时候不会?一个指针delete后是什么状态?

reference1:使用delete删除指针(转) - romanten - 博客园 (cnblogs.com)

​ 这篇文章说delete后成了野指针在内存里乱指一通,它作为地址的值还是有效的,还可以访问它以前指向的内存,不过那片内存被重新格式化了;此时如果误用p指针,仍然可以修改内存的值和从该处取出数值,但此时数据不受保护,该内存空间可能被重新被分配给别的变量。

​ 通过实践后发现delete后的指针并没有指向一个随机的地址,要么是指向之前的地址,要么是指向了00008123这个地址,所以它不是一个野指针,如下所述:

结论

​ 从我个人的理解来看delete过后指针是变成了一个悬空指针,因为从野指针的定义上,”野指针“是未被初始化的指针并且指向的位置是不可知的,而“悬空指针”是指向一块曾经保存数据对象但现在已经无效的内存的指针,它的地址依然是指向之前所指向的地址,只是该内存空间被释放且不能再使用,若使用解引用操作会直接报错,更符合delete之后的情况。但是通过实验发现一个问题,delete一个局部变量的指针后会将地址值变为00008123,而delete一个成员变量则是正常的指向之前的值。

问题
#include <iostream>

using namespace std;

class Test {
public:
	Test(int _number) {
		p = new int(_number);
	}
	~Test() {
		cout << "address: " << p << endl;
		delete p;
		cout << "after delete address: " << p << endl;
	}
public:
	int *p;
};

void try1() {
	Test t1(120);
}

void try2() {
	int* q = new int(120);
	cout << "address: " << q << endl;
	delete q;
	cout << "after delete address: " << q << endl;
}

int main()
{
	try1();
	try2();
	return 0;
}

输出如下:

address: 0106D078
after delete address: 0106D078
address: 0106D078
after delete address: 00008123

这个问题可能是VS的编译器导致的,目前还不知道原因是什么。

可参考的因素:可能是为了方便及早发现已经释放的内存,而将这个无效值:00008123直接插入到delete语句。如果使用以下的操作可以阻止普通函数修改指针。

delete (int*) p;   //传右值的操作
delete (p = p);	   //有副作用的赋值
int * volatile p;  //重新赋值
delete q;          //成员变量
使用注意:

我们需要注意的是在将指针delete过后,将其赋值为空。即 p = nullptr。或者使用智能指针shared_ptr来代替new和delete申请动态内存的操作。

reference2:野(wild)指针与悬空(dangling)指针 - veli - 博客园 (cnblogs.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值