48

mallocメソッドを使用して整数の配列を作成したいと思います。この配列をグローバルにして、プログラムのどこでも使用できるようにしたいと思います。次のようなヘッダーファイルにコードを挿入しました。

static int *pieces;

次に、そこに必要な数値を入力する関数があります。関数は名前空間にあり、名前空間は独自の.cppファイルに実装されています。ただし、ヘッダーファイルをmain.cにインポートし、次のような配列を作成する名前空間から関数を呼び出します。

pieces = malloc(sizeof(int) * 128);

しかし、mainの配列内の数値にアクセスしようとすると(配列を作成する関数を呼び出した後)、クラッシュして、ピースが初期化されていないと表示されます。しかし、私が持っている関数では、それを作成し、その中の数値をうまく操作することができます。ピースを静的変数にすることで、どこかで関数が変更(または設定)されるたびに、それがどこでも変数の使用に影響を与えるという印象を受けました。基本的に私が言おうとしているのは、呼び出した関数で設定したのに、なぜメインでピースが設定されていないように見えるのかということです。

4

4 に答える 4

97

Staticは多くの意味を持つキーワードであり、この特定のケースでは、グローバルではないことを意味します(言い換え)

これは、各ファイルに変数の.cpp独自のコピーがあることを意味します。したがって、で初期化するとmain.cppでのみ初期化されmain.cppます。他のファイルにはまだ初期化されていません。

これを修正する最初のことは、キーワードを削除することstaticです。これにより、「複数の定義の問題」が発生します。これを修正するには、変数を.cppファイルで定義し、externでヘッダーファイルで宣言する必要があります。


編集:あなたはそれにメモリを割り当てているだけで、初期化としてカウントされません。割り当て後、メモリを0に初期化する必要があります。

new int[128]()より冗長なmalloc構文の代わりに使用できます。これにより、初期化も実行されますか?または、簡単な道を進んで(それが目的です)、使用することもできますstd::vector

于 2013-01-16T01:13:26.563 に答える
29

重要なのはこれです:

static int *pieces;

あなたはそれをあなたのヘッダーに入れると言いました。これは、シンボルをエクスポートする方法ではありません。ヘッダーを含むすべてのファイルは、と呼ばれる初期化されていないポインターの独自の静的バージョンを取得しますpieces

代わりに、これをヘッダーに入れます。

extern int *pieces;

extern int init_pieces();

そして、ソースファイルでこれを行います:

static const size_t num_pieces = 128;

int *pieces = 0;

int init_pieces()
{
    pieces = malloc( num_pieces * sizeof(int) );
    return pieces != NULL;
}

これで、ヘッダーを含めると、ソースファイルは別の場所から取得することがわかりpieces、リンカーがどこから取得するかを待機します。また、配列の「init」関数を提案しました。ただし、「リリース」関数は入れませんでした。

これはすべてCであり、C++ではないことに注意してください。C ++を使用している場合は、実際に使用する必要があります。newさらに良いのは、を使用することvectorです。

また、C ++で静的を使用する場合は、次の点に注意してください。C++の静的初期化順序

于 2013-01-16T01:16:17.470 に答える
9

C ++ 17標準ではinline、静的の代わりに指定子を使用できます。変数の場合、これはすべてのオブジェクトユニットが変数のコピーを持つことを意味しますが、リンカはそのうちの1つだけを選択します。または、cppreferenceに記載されているように:

インライン関数またはインライン変数(C ++ 17以降)には、次のプロパティがあります。

1)各定義が異なる変換単位に表示されている限り(非静的インライン関数および変数の場合(C +以降)、プログラム内にインライン関数または変数の定義が複数存在する場合があります(C ++ 17以降) +17))すべての定義は同一です。たとえば、インライン関数またはインライン変数(C ++ 17以降)は、複数のソースファイルに#includeされたヘッダーファイルで定義できます。

2)インライン関数または変数の定義(C ++ 17以降)は、アクセスされる変換ユニットに存在する必要があります(必ずしもアクセスポイントの前にある必要はありません)。

3)外部リンケージ(静的宣言されていないなど)を持つインライン関数または変数(C ++ 17以降)には、次の追加のプロパティがあります。

1) It must be declared inline in every translation unit.

2) It has the same address in every translation unit.

(ソース)でサポート:

  • バージョン19.12以降のMSVC(VS 2017 15.5)
  • GCC 7
  • Clang 3.9
  • ICC 18.0

この場合、それはあなたが置き換えることができることを意味します

static int *pieces;

inline int *pieces;
于 2018-10-19T07:40:17.847 に答える
2

さまざまなアーキテクチャでの高性能コードの場合、一般的なnewではなくmalloc-y割り当てが必要になる場合があります。これは、mymalloc()のようなものでラップしてから、アーキテクチャに依存する関数を使用するためです。たとえば、適切な配置を実装してキャッシュミスを回避し、IBM(Bluegene)やIBM(Bluegene)などのハードウェアメーカーが提供するその他の優れた機能を実行します。 Intel(MIC)。これらの最適化された割り当てルーチンはすべて、mallocタイプのフレームワークを備えています。

于 2016-06-18T20:20:28.103 に答える