destroy() 中的访问冲突
access violation in destroy()
我正在尝试使用手动内存管理来管理昂贵对象的生命周期,并且在我的单元测试期间,在本例中 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 "for" 你...这意味着你从未真正释放它。改为执行 Foo tmp = _p; destroy(_p); free(cast(void*) tmp);
或类似的操作,以便在 destroy 调用之后保留引用的临时副本。但这不是导致崩溃的原因,这只是内存泄漏。
崩溃是因为 class 的 Foo.sizeof
是 reference 的大小,而不是实例的大小。对于 classes,你想要 malloc(__traits(classInstanceSize, Foo))
。该文档提到这是其先决条件之一:http://dpldocs.info/experimental-docs/std.conv.emplace.3.html
这导致了您的崩溃,因为您没有为 vtable 分配足够的 space(因此 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
您在向该结构传递 class 引用时也应该小心,因为如果它没有被分配或有另一个引用,您将遇到悬空问题。
我正在尝试使用手动内存管理来管理昂贵对象的生命周期,并且在我的单元测试期间,在本例中 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 "for" 你...这意味着你从未真正释放它。改为执行 Foo tmp = _p; destroy(_p); free(cast(void*) tmp);
或类似的操作,以便在 destroy 调用之后保留引用的临时副本。但这不是导致崩溃的原因,这只是内存泄漏。
崩溃是因为 class 的 Foo.sizeof
是 reference 的大小,而不是实例的大小。对于 classes,你想要 malloc(__traits(classInstanceSize, Foo))
。该文档提到这是其先决条件之一:http://dpldocs.info/experimental-docs/std.conv.emplace.3.html
这导致了您的崩溃,因为您没有为 vtable 分配足够的 space(因此 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
您在向该结构传递 class 引用时也应该小心,因为如果它没有被分配或有另一个引用,您将遇到悬空问题。