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 に答える