Jerry
1
如题,我用 c++ 按照如下代码创建了一个简单的类:
struct Sth {
int a;
int b;
Sth();
};
Sth::Sth() {
a = b = 0;
}
可我试图创建再销毁这个类创建的一个实例时:
int main() {
Sth sth;
delete &sth; // ERROR!!!
return 0;
}
它报告了错误:
/home/was/cpp/a.cpp: 在函数‘int main()’中:
/home/was/cpp/a.cpp:8:11: 警告:‘void operator delete(void*, long unsigned int)’ called on unallocated object ‘sth’ [-Wfree-nonheap-object]
8 | delete &sth;
| ^~~
/home/was/cpp/a.cpp:7:7: 附注:在此声明
7 | Sth sth = *(new Sth);
| ^~~
munmap_chunk(): invalid pointer
为什么指针无效呢?
Jerry
4
这个其实是我在写数据结构时发现的一个问题。这是我从我的数据结构代码中浓缩的,所以呈现出的比较奇葩
现在改了一下
yyjjl
5
你这个写法,明显是内存 leak 了。。。。
先在堆上分配一个 Sth 对象,然后复制给栈上一个对象。。
然后想要delete栈上的一个对象
1 个赞
Jerry
6
那么有什么办法去delete堆上的对象吗 (在不更改实例的创建方法的情况下) ?
yyjjl
7
int main() {
Sth *sth=new Sth{};
delete sth;
return 0;
}
2 个赞
你这是 automatic,为啥要手动 delete 呢?
Sth 的 destructor 会在退出 main () 时自动调用,不需要手动 destroy。
1 个赞
Jerry
12
仔细看您的贴子,再看看7楼,顿悟:
我在 我写的数据结构中 用new手动建立在堆上的东西 都在clear()
方法中删除了,而automatic的会自动销毁
所以我好像不需要写destroy()
了!这个问题不用去管了!「欣喜若狂」「万分感激」
代码有两个问题
1 delete不是简单的语义上释放内存,他只能用于new返回的堆内存。堆内存有自己的数据结构,delete会根据传递的指针,按照chunk的数据结构对字段做检查,包括确定回收的范围等。这也是报错的原因
called on unallocated object ‘sth’
delete检查给定的指针,结果发现对应的字段偏移显示这个内存还未分配,你尝试delete一个未分配的内存,所以报错(不过如果你能在栈上手动构造好堆的chunk结构,是可以不报错的),不过这些细节一般不玩二进制安全是用不到的。感兴趣可以github看下https://github.com/shellphish/how2heap
这个项目。
2 你这里创建的sth对象在栈上,main函数返回时会销毁这个对象,你手动再释放肯定出问题,语义上双重释放了(虽然你这里用的delete不会成功)。
1 个赞