触发“分段错误”的超奇怪问题
我不会深入研究这个问题(代码库已经有数千行而且相当复杂),所以我会尝试将…“窗口”缩小到我发现的位置。
这是触发“分段错误”的例程:
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"); } }
几点说明:
- 声明的方法只是“绑定”,因此可以直接从C代码(实际上是Bison)调用本机例程。
- 使用
Statements
对象和子类Statement
对象调用Statements_add
函数。
现在,它的奇怪之处:
- 错误不会一直发生(事实上它不会像99%的时间那样发生),但是当它发生时,
s.add(st);
声明似乎是罪魁祸首。 - 永远不会是2个参数之一(
s
,st
)null
。 - 现在,如果我评论2
if... writeln... typeid
语句,那么错误就在那里。 - 如果我取消注释它们(它们什么都不做,是吗?),它总是有效 – 固定 – 宾果游戏!
这是怎么回事???
更多细节:
- 编译器: DMD64 D Compiler v2.065
- 调试器: lldb
- 操作系统: OSX 10.9.2
如果要将D代码中分配的对象的唯一引用从D堆传递给非D代码,则必须将其注册为GC根 ,或者将代码更改为使用malloc
而不是从托管D堆分配。 否则,GC会认为该对象未使用,并将其收集到空闲内存中。