考虑以下因素:
tbModelHFrame = new TbModelHeaderFrame(this, storage->getDataBase());
我想删除tbModelHFrame内存的正确方法是
delete tbModelHFrame;
右?
如何检查内存是否真正发布?
答案 0 :(得分:10)
如何检查内存是否真正发布?
你没有。
C ++无法判断指针是指向内存中的有效对象还是随机区域。后者包括一个在某些时候有效的区域,但从那时起就被删除了。
开发人员需要以不会发生这种情况的方式组织他们的代码。
语言为您提供的唯一保证就是delete
来电永不失败。因此,如果您在对象上调用delete
一次,则可以合理地确定对象已正确销毁且内存已释放。只是不要试图再次访问它,否则你将遇到麻烦。
答案 1 :(得分:2)
答案 2 :(得分:1)
根据删除操作符reference:
[..]在所有情况下,如果ptr是空指针,那么标准库 释放函数什么都不做。
如果指针传递给 标准库解除分配函数未从中获取 相应的标准库分配功能,的行为是 未定义即可。
标准库释放函数返回后, 所有指向解除分配存储的任何部分的指针都成了 无效。
使用以这种方式变得无效的指针,甚至 将指针值复制到另一个变量中是未定义的 行为。 (直到C ++ 14)
通过指针变为间接 以这种方式无效并将其传递给释放功能 (双删除)是未定义的行为。任何其他用途是 实现定义的。
因此,如果删除指针有问题,则未定义行为。
答案 3 :(得分:0)
问题的前提是错误的:如果delete
没有释放内存,那么您的堆已损坏且您的应用程序已经可以执行任何操作,包括格式化您的硬盘驱动器。因此,如果涉及delete
仅仅是QScopedPointer<TbModelHeaderFrame> tbModelHFrame(
new TbModelHeaderFrame(this, storage->getDataBase())
);
...
tbModelHFrame->something(); // do something with it
那么你就会遇到更大的问题。所以,不要担心。只要避免由于你自己的代码中的内存错误而弄乱了你的堆,你就没事了。
无论如何,你不应该使用裸指针作为拥有指针。这是C ++,而不是C。
使用智能指针:
class Foo {
QScopedPointer<TbModelHeaderFrame> m_modelHFrame;
...
};
Foo::Foo() :
m_modelHFrame(new TbModelHeaderFrame(this, storage->getDataBase())) {
...
}
就是这样。当指针超出范围时,将释放内存。你不必担心它。
指针也可以是类成员:
Foo::Foo() : ... {
m_modelHFrame.reset(new TbModelHeaderFrame(this, storage->getDataBase()));
...
}
或
#make some dummy data
d <- data.frame(subj_id = c(1:1000,1:1000),
cond = c(rep("Control",1000),rep("Exposed",1000)),
resp = c(rnorm(1000,10,1),rnorm(1000,10,2)) # make different variances
)
var.test(d$resp[d$cond=="Exposed"],
d$resp[d$cond=="Control"])
# F test to compare two variances
#
# data: d$resp[d$cond == "Exposed"] and d$resp[d$cond == "Control"]
# F = 4.0976, num df = 999, denom df = 999, p-value < 2.2e-16
# alternative hypothesis: true ratio of variances is not equal to 1
# 95 percent confidence interval:
# 3.619378 4.638939
# sample estimates:
# ratio of variances
# 4.097569
现代C ++代码的设计应该不使用手动内存管理,除非出于理解的原因绝对必要。在大多数情况下,现代C ++中的裸指针和手动内存管理是设计糟糕的标志,而不是必需品。
TL; DR:现代C ++ / Qt代码可以而且应该读得像Python一样:)