4

私は C や C++ の経験がないので、静的配列には少し戸惑います。それらは何のため?それらがスタックに割り当てられるのはなぜですか?

パフォーマンス上の利点があると思います。スタック割り当てが高速になり、ガベージ コレクションが不要になります。しかし、なぜコンパイル時に長さを知る必要があるのでしょうか? 実行時に固定サイズの配列を作成し、スタックに割り当てることはできませんでしたか?

D の動的な配列またはスライスは、ポインターと長さのプロパティを含む構造体によって表されます。静的配列にも同じことが当てはまりますか? それらはどのように表されますか?

それらを関数に渡すと、(ref を使用しない限り) 全体がコピーされますが、その背後にある理論的根拠は何ですか?

D では動的配列とスライスが静的配列よりもはるかに重要であることを認識しています。そのため、ドキュメントではそれらについてあまり詳しく説明していませんが、もう少し背景を知りたいと思っています。静的配列の特殊性は、スタック割り当ての仕組みに関係していると思います。

4

2 に答える 2

6

静的配列はalloc、メモリリーク(割り当てられた配列を解放するのを忘れたとき)、二重解放(...の結果として)、ダングリングポインタ(すべてGCで回避できる手動メモリ管理の危険性)

これは、

int foo(char* inp){
    char[80] buff;
    strcpy(inp,buff);//don't do this this is a invite for a buffer overflow
    //...
    return 1;
} 

割り当てたすべてのものがプログラムの過程で一度だけ解放されたことを確認する必要があるalloc/free呼び出しの代わりに、一般的でした

技術的には、スタックに動的に割り当てることができます(必要に応じてアセンブリを使用)が、長さは実行時にのみ認識され、コンパイラが適用する可能性のある最適化が少なくなるため、コードに問題が発生する可能性があります(例)

静的配列は、スタックでの高速割り当てが可能なため、主にバッファに使用されます

ubyte[1024] buff=void;//assigning void avoids the initializer for each element cause we are writing to it first thing anyway
ubyte[] b;
while((b=f.rawRead(buff[])).length>0){
     //...
}

それらは暗黙的に配列のスライスに変換できるので(または明示的にslice演算子[]を使用して)、通常の動的配列とほぼ互換的に使用できます。

于 2012-02-12T02:53:47.887 に答える
5

静的配列は、D2 の値の型です。静的配列がなければ、構造体に実際に格納されている 100 個の要素を構造体に含める簡単な方法はありません。

静的配列は、そのサイズを型の一部として保持します。これにより、たとえば次のように宣言できます。alias ubyte[16] IPv6Address;

C とは異なり、D2 静的配列は完全に値型です。これは、構造体などの関数に値で渡されることを意味します。静的配列は、通常、メモリの割り当てとコピーに関する限り、N 個のメンバーを持つ構造体のように動作します。

ちなみに、allocaスタックに可変量のメモリを割り当てるために使用できます。C にも可変長配列があります。

于 2012-02-12T08:33:56.927 に答える