为什么这个 D 程序会抛出一个奇怪的访问冲突异常?
Why does this D program throw a strange access violation exception?
只要以下程序是 运行,它就会崩溃并出现此 st运行ge 异常:
"Exception thrown at 0x00B31028 in dfun.exe: 0xC0000005: Access violation reading location 0x00000000."
我正在 visual studio 中使用 visuald 和 dmd 进行编译。不确定要提供更多信息,请问...
module dfun;
import std.stdio;
class Event(Args...)
{
private void function(Args)[] _funcArray;
public this()
{
}
public void addHandler(void function(Args) handler)
{
_funcArray.length++;
_funcArray[$ - 1] = handler;
}
public void opCall(Args args)
{
foreach(func; _funcArray)
{
func(args);
}
}
}
void foo(int a, char c)
{
writeln(a, c);
}
int main()
{
Event!(int, char) doIt;
doIt.addHandler(&foo);
doIt(5, 'a');
readln();
return 0;
}
但是如果代码改成这样,基本功能是一样的:
module dfun;
import std.stdio;
void foo(int a, char c)
{
writeln(a, c);
}
int main()
{
//Event!(int, char) doIt;
//doIt.addHandler(&foo);
void function(int, char)[] func;
func.length++;
func[0] = &foo;
func[0](5, 'a');
readln();
return 0;
}
它工作得很好。
class 中断了什么?
您没有在这些行上初始化事件:
Event!(int, char) doIt;
doIt.addHandler(&foo);
类 是引用类型,初始值是 null
(.init
)。这意味着您需要显式初始化 doIt
:
Event!(int, char) doIt = new Event!(int, char)();
可以使用 auto
:
稍微缩短
auto doIt = new Event!(int, char);
这应该可以解决这个问题。这里有一个问题:Event
是否需要成为 class 并具有引用语义,或者结构是否也能满足您的目的?如果您可以使用结构,则无需对其进行初始化。
您的 addHandler function
中还有一个小毛病:不需要 ++length; arr[$-1]
舞蹈 - D 有 concatenation operator ~:
public void addHandler(void function(Args) handler)
{
_funcArray ~= handler;
}
只要以下程序是 运行,它就会崩溃并出现此 st运行ge 异常:
"Exception thrown at 0x00B31028 in dfun.exe: 0xC0000005: Access violation reading location 0x00000000."
我正在 visual studio 中使用 visuald 和 dmd 进行编译。不确定要提供更多信息,请问...
module dfun;
import std.stdio;
class Event(Args...)
{
private void function(Args)[] _funcArray;
public this()
{
}
public void addHandler(void function(Args) handler)
{
_funcArray.length++;
_funcArray[$ - 1] = handler;
}
public void opCall(Args args)
{
foreach(func; _funcArray)
{
func(args);
}
}
}
void foo(int a, char c)
{
writeln(a, c);
}
int main()
{
Event!(int, char) doIt;
doIt.addHandler(&foo);
doIt(5, 'a');
readln();
return 0;
}
但是如果代码改成这样,基本功能是一样的:
module dfun;
import std.stdio;
void foo(int a, char c)
{
writeln(a, c);
}
int main()
{
//Event!(int, char) doIt;
//doIt.addHandler(&foo);
void function(int, char)[] func;
func.length++;
func[0] = &foo;
func[0](5, 'a');
readln();
return 0;
}
它工作得很好。 class 中断了什么?
您没有在这些行上初始化事件:
Event!(int, char) doIt;
doIt.addHandler(&foo);
类 是引用类型,初始值是 null
(.init
)。这意味着您需要显式初始化 doIt
:
Event!(int, char) doIt = new Event!(int, char)();
可以使用 auto
:
auto doIt = new Event!(int, char);
这应该可以解决这个问题。这里有一个问题:Event
是否需要成为 class 并具有引用语义,或者结构是否也能满足您的目的?如果您可以使用结构,则无需对其进行初始化。
您的 addHandler function
中还有一个小毛病:不需要 ++length; arr[$-1]
舞蹈 - D 有 concatenation operator ~:
public void addHandler(void function(Args) handler)
{
_funcArray ~= handler;
}