我不会深入探讨这个问题(代码库已经有数千行并且相当复杂),所以我会尽量减少...“窗口”到我发现的内容。
这是触发“段错误”的例程:
extern (C)
{
void* Statements_new() { return cast(void*)(new Statements()); }
void Statements_add(Statements s, Statement st)
{
//writeln("In here");
if (s is null) writeln("StatemenTS are null");
else writeln("not null : "~ typeid(s).name);
if (st is null) writeln("statement is null");
else writeln("not null : " ~ typeid(st).name);
s.add(st);
//writeln("Out of here");
}
}
一些注意事项:
- 声明的方法只是“绑定(bind)”,因此可以直接从 C 代码(实际上是 Bison)调用 native 例程。
- 使用
Statements
对象和子类Statement
对象调用Statements_add
函数。
现在,它的怪异之处:
- 错误不会一直发生(实际上它不会像 99% 的时间那样发生),但是当它发生时,
s.add(st);
语句似乎是罪魁祸首。 - Never ever 是两个参数之一 (
s
,st
)null
。 - 现在,如果我注释 2 个
if...writeln...typeid
语句,错误就在那里。 - 如果我取消对它们的注释(它们什么都不做,是吗?),它总是有效 - 修复 - 宾果游戏!
这是怎么回事???
更多细节:
- 编译器:DMD64 D 编译器 v2.065
- 调试器: lldb
- 操作系统: OSX 10.9.2
最佳答案
如果您将 D 代码中分配的对象的唯一引用从 D 堆传递到非 D 代码,那么您必须要么 register it as a GC root ,或更改您的代码以使用 malloc
而不是从托管 D 堆分配。否则GC会认为该对象未被使用,将其回收释放内存。
关于c - super 奇怪的问题触发 "Segmentation Fault",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23247986/