gpt4 book ai didi

destructor - destroy() 中的访问冲突

转载 作者:行者123 更新时间:2023-12-01 11:16:41 27 4
gpt4 key购买 nike

我正在尝试使用手动内存管理来管理昂贵对象的生命周期,在我的单元测试期间,我的程序似乎因 destroy(bar) 下的主要方法中的访问冲突而崩溃在这个例子中。这是我遇到访问冲突问题的最小示例。

我不明白出了什么问题。

class Foo { int i;}

struct Bar
{
Foo _p;
this(Foo foo)
{
_p = foo;
}

~this() {
import core.stdc.stdlib : free;
if (_p !is null)
{
destroy(_p);
free(cast(void*)_p);
_p = null;
}
}
}


void main(string[] argv)
{
import std.conv;
import core.stdc.stdlib;

Foo foo = emplace(cast(Foo) malloc(Foo.sizeof));

Bar bar = Bar(foo);
destroy(bar);
}

最佳答案

请注意,destroy 将 _p 设置为 null “为”您......这意味着您从未真正释放它。执行 Foo tmp = _p;销毁(_p); free(cast(void*) tmp); 而不是,或者类似的东西,所以你在 destroy 调用之外保留引用的临时副本。但这不是导致崩溃的原因,这只是内存泄漏。

崩溃是因为类的 Foo.sizeofreference 的大小,而不是实例的大小。对于类,您需要 malloc(__traits(classInstanceSize, Foo))。该文档提到这是其先决条件之一:http://dpldocs.info/experimental-docs/std.conv.emplace.3.html

这会导致您的崩溃,因为您没有为 vtable 分配足够的空间(因此 emplace 也可能损坏了内存,由于您的转换而逃避了类型检查!)。我会 malloc 并对其进行切片而不是强制转换。

// malloc the instance size then slice it to get a type-safe representation
void[] memory = malloc(__traits(classInstanceSize, Foo))[0 .. __traits(classInstanceSize, Foo)];
emplace!Foo(memory); // emplace a new one in that memory

在将类引用传递给该结构时,您也应该小心,因为如果它没有被分配或者如果有另一个引用,您将遇到悬空问题。

关于destructor - destroy() 中的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49949112/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com