6

我正在学习 D,并且对我遇到的错误感到困惑。

考虑以下:

module helloworld;

import std.stdio;
import std.perf;

ptrdiff_t main( string[] args )
{
     auto t = new PerformanceCounter;    //From managed heap
     //PerformanceCounter t;             //On the stack

     t.start();
     writeln( "Hello, ", size_t.sizeof * 8, "-bit world!" );
     t.stop();

     writeln( "Elapsed time: ", t.microseconds, " \xb5s." );

     return 0;
} //main()

产生一个非常可敬的:

Hello, 32-bit world!
Elapsed time: 218 µs.

现在考虑当我尝试在堆栈上初始化 PerformanceCounter 而不是使用托管堆时会发生什么:

 //auto t = new PerformanceCounter;  //From managed heap
 PerformanceCounter t;               //On the stack

产量:

--- killed by signal 10

我难住了。关于为什么会中断的任何想法?(Mac OS X 10.6.4 上的 DMD 2.049)。在此先感谢您对 n00b 的帮助。

4

3 回答 3

5

您似乎将 C++ 类与 D 类混合在一起。

D 类总是通过引用传递(与 C++ 类不同),并且PerformanceCounter t不在堆栈上分配类,只是一个指向它的指针。

这意味着t设置为,null因为它null是指针的默认初始值设定项 - 因此是错误。

编辑:您可以将 DFoo类视为 C++ 的Foo*.

如果您希望在堆上分配它,您可以尝试使用结构来代替 - 它们也可以有方法,就像类一样。然而,他们没有继承权。

于 2010-10-23T22:07:34.907 回答
3

最明显的答案是使用struct. 如果您使用的库是您无法控制的,并且堆分配是一个性能问题,您可以使用该std.typecons.scoped功能在堆栈上不安全地分配类实例。实例仍然通过引用传递,如果它的生命周期超过当前堆栈帧的生命周期,将导致未定义的行为。根据scopeanoncow 的答案,关键字将起作用,但计划在 D2 中弃用。

于 2010-10-23T23:42:26.757 回答
1

谢谢,蒂姆。

感谢您的回答,我能够在http://www.digitalmars.com/d/2.0/memory.html找到以下内容:


在堆栈上分配类实例

类实例通常分配在垃圾收集堆上。但是,如果它们: 被分配为函数中的局部符号 使用 new use new 分配,不带参数(允许构造函数参数)具有作用域存储类,则它们被分配在堆栈上。这比在实例上执行分配/释放循环更有效。但请注意,对对象的任何引用都不会在函数返回后继续存在。

class C { ... }

scope c = new C();  // c is allocated on the stack
scope c2 = new C(5);    // allocated on stack
scope c3 = new(5) C();  // allocated by a custom allocator

如果该类具有析构函数,则该析构函数保证在类对象超出范围时运行,即使该范围通过异常退出也是如此。


我的代码现在读取

scope t = new PerformanceCounter();  //On the stack 

这(据称)在堆栈上分配并运行良好。:)

再次感谢!

于 2010-10-23T22:30:50.617 回答