静的配列のサイズを変更する

We have declared an array like below in our code. array is to be handled on the stack itself. we are not allocating any memory on heap with malloc or new

char a[20000];

これで 20kb ではなく 1800000(180kb)に変更する必要があります。 以下のように:

char a[1800000];

我々はちょうどいくつかのデータで配列を埋めることです。 これは有効なことですか?

私たちが直面する可能性のある問題は何ですか? 私は値が大きすぎるように思えるだけです。 この必要性を回避するためのより良い方法はありますか?

私はsolaris unixプラットフォームで作業しています。

3
うん、あなたは正しいです。私はちょうどそれを丸めたが、それはここで過度の懸念ではない:)
追加された 著者 Vijay,
あなたは "ここで静的配列とは、配列自体がスタック上で扱われるという意味です"と言う。それは「静的」という意味ではありません。静的オブジェクトは永続的なものなので、スタック上に存在することはできません。実際には「自動」を意味しますか?
追加された 著者 Mike Seymour,
16ビットプラットフォームをサポートする必要がありますか?
追加された 著者 Mike Seymour,
realloc を使用してください。 cplusplus.com/reference/clibrary/cstdlib/ realloc 私は質問を閉じることを提案する。
追加された 著者 INS,
サイズは、スタックを使用するのが妥当かどうかを決める際に重要なので、180 KBか1.7 MBかを明確にする必要があります。たとえば、Windowsでは、180KBは完全に合理的です。ただし、デフォルトのスタックサイズが1MBであるため、1.7 MBは動作しません(コンパイラ設定を変更せずに)。
追加された 著者 cbranch,
注:1,800,000バイトは、180 KBではなく、約1.7 MBです。
追加された 著者 cbranch,
私はサイズを char a [1024 * 1024 * 20]/* < - 20 kbytes */として定義します。サイズを変更しようとすると、読みやすくなり、エラーが起こりにくくなります。
追加された 著者 fogbit,

7 答え

このように宣言された変数のサイズの大幅な増加は、スタックに影響を与える可能性があります。これを std :: vector に置き換えると、ヒープから必要なメモリが大量に生成されます。これは結局、 C ++ というタグが付けられています。

5
追加された
実際には、疑問は明らかに "静的配列によって、配列自体がスタック上で扱われることを意味する"
追加された 著者 Chad,
downvoteを理解するのが大好きです。英語を第2言語として使用しているチームと一緒に仕事をしたことがある場合は、関数のローカルスコープを持つ非ダイナミックセグメントについて簡単に質問できることがわかります。
追加された 著者 Chad,
std :: vector に移動することについての引数はありますか?メモリ管理は vector によって処理されるので、これを malloc/new
追加された 著者 Chad,
問題はそのことを暗示していますが、投稿されたコードからは明らかではありません。これが関数のローカルスコープで宣言されていれば、コンパイルさえすれば結果が出る可能性があります。
追加された 著者 Chad,
@Chadあなたは正しいです。関数のローカルスコープを持つ非動的セグメントに関する質問のように見えます。
追加された 著者 Jagannath,
std :: vectorの使用を提案するための+1。
追加された 著者 Jagannath,
static はスタックに実装されないでしょう。
追加された 著者 Joe McGrath,

あなたが実際に "静的"を意味し、これは合理的に現代的なプラットフォームの場合、そのサイズの静的オブジェクトに問題はありません。 32ビットプラットフォームでは、低いギガバイトになったときに問題が発生し始めます。 64ビットプラットフォームでは、唯一の制限は使用可能なストレージ容量です。

However, you also say this is on the stack, implying that it's automatic rather than static. This could be a problem, especially in a multi-threaded program, since the stack has a fixed size. You should therefore avoid putting large objects on the stack; make them static if that's appropriate, or dynamic otherwise - create it with malloc in C, and use a std::vector in C++.

万一、8ビットまたは16ビットプラットフォームをサポートする必要がある場合は、64kbを超えるオブジェクトを作成することは困難または不可能です。この場合、64 KB以上のRAMがあると仮定すると、より小さな部分に分割したい場合があります。それ以外の場合は、テープやフロッピーディスクからページを保存して読み込むことは可能ですが、非常に遅くなります。

2
追加された

このアレイは本当に静的ですか? static キーワードがないためです。

スタック上にこのような大きな配列を作成することは、あなたが本当にすべきことではありません。コンパイラによっては、プログラムがクラッシュする可能性があり、プラットフォームやOSによってはクラッシュする可能性もあります。

このような大きな配列を作成する必要がある場合は、C ++の malloc()またはC ++の new

char *array = malloc(1800000 * sizeof(*array));

これははるかに移植性があり、より安全です。また、スタック上のデータのサイズを変更することはできません。したがって、ヒープを使用してください。

HTH、  CK

2
追加された
OPは、ファイルスコープで割り当てられたすべての変数が取得する静的記憶期間を参照している可能性があります。
追加された 著者 Lundin,
これがキーワード「静的」を求めた理由ですが、静的な記憶域も限られていることが多く、ヒープはRAMによって制限されます。ヒープを使って、ルーク! :-)
追加された 著者 ckruse,

この範囲のサイズには、Mallocまたはnewを使用します。通常、ヒープはより大きな割り当てに適しています。サイズ変更も簡単です。これは、関数スコープ内で割り当てが発生してスタックに配置される場合に特に当てはまります。これらがグローバルであれば、それほど悪くはありません。しかし、可能であれば、私はヒープ割り当てをしています。

1
追加された
1.8MBが十分であると確信しているので、サイズ変更は不要です
追加された 著者 Vijay,
ヒープがデータセグメントよりも優れている理由は何ですか?
追加された 著者 Mike Seymour,
@チャド:申し訳ありませんが、私はちょうど "静的"という言葉を読んでいます。正解はむしろOPが "静的"と "積み重ね"によって何を意味するかによって決まります。
追加された 著者 Mike Seymour,
@MikeSeymour static キーワードが不足しているという疑問は、配列が "スタック自体で処理される"ということも明記しています。だから、ヒープは、このサイズのセグメントに適しています。
追加された 著者 Chad,

いくつかの基本的な概念を明確にするために:

静的なキーワードがあり、静的な記憶期間があります。これは、変数がプログラムの実行中も保持され、変数のインスタンスが1つしか割り当てられないことを意味します。静的な保存期間を持つオブジェクトは、RAMの特定のセグメントに格納され、 .bss と呼ばれることがよくあります。 。静的またはファイルスコープ(グローバル)で宣言されたすべての変数は、静的な記憶期間を持ちます。静的記憶期間を持つ変数は、C/C ++標準によってゼロに初期化されることが保証されています。

スタックは、ローカル変数と関数パラメータが最も頻繁に割り当てられるRAMの動的部分です。スタックに割り当てられた変数は、通常自動的に変数と呼ばれ、コンパイラが自動的にこの変数を処理し、スタック上にある可能性のある最適な場所に割り当てますが、CPUレジスタやキャッシュメモリなどにも割り当てます。 C/C ++では auto というキーワードを使用する必要はありません。すべてのローカル変数とパラメータはデフォルトで自動です。自動ストレージを持つ変数には、明示的に初期化されない限り、ガベージ値が含まれます。

ヒープは、RAMのもう一つの動的部分です。これは、mallocまたは new で明示的に変数を割り当てるときにのみ使用されます。ヒープは、動的メモリ割り当て(フリーストア管理とも呼ばれます)について話すときに通常参照するものです。動的に割り当てられた変数には、明示的に初期化されない限り、ガベージ値が含まれます。

ほとんどのコンピュータでは、静的セグメントとヒープはRAMの量によってのみ制限されますが、スタックは固定サイズで制限されています。 Unixのようなマルチタスキングシステムでは、コンピュータのプロセスごとに1つのスタックが存在します。私はどのくらいの大きさの.bssやUnix/Solarisのスタックが可能かはわかりませんが、コンピュータの古さに依存していると思います。古いマシンではスタックに1.7MBの割り当てに問題がある可能性があります。私はUnixマシンについてはあまりよく分かりませんが、そのような大量のデータをすべてヒープ上に動的に割り当てることが推奨されています(これはPC上で行うことです)。

1
追加された
@ダン:私はそれを "初期化されていない"あなたは、プログラマによって明示的に初期化されていない静的ストレージの変数を参照してください?私はこれがすべてのコンパイラに普遍的に当てはまるとは確信していません。私は、暗黙的に明示的に初期化された変数の間に差をつけない埋め込み型変数をいくつか見てきましたが、そのすべてを.bssに置き換えました。
追加された 著者 Lundin,
静的な保存期間を持つオブジェクトがRAM内の特定のセグメントに格納されているとしばしば言います(bss と呼ばれることがあります)。「オブジェクト」の前に Uninitialized ;初期化されたオブジェクトは通常、.bssではなく別のセグメントに配置されます。また、C/C ++標準で static storage durationの変数がゼロに初期化されることが保証されている場合は、初期化されていない変数に編集することをおすすめします。
追加された 著者 Dan,

サイズが重要ではない通常のプログラムでは、例えば画像を撮るだけで、それらはmbsとmbsのデータを保持します。時にはギグもあります。あなたのプログラムが最新のコンピュータ上で動作するならば、私はそのサイズについて全く心配しません。

realloc (cを使用している場合)で実行時にデータのサイズを増やすことができるので、動的に割り当てられるオブジェクトの中にそのデータをカプセル化することを検討すべきです。これが正しく行われると、実装の詳細を隠すのにも役立ちます。

0
追加された
スタックサイズと実行可能なサイズの問題 - どちらもヒープ割り当てよりはるかに制限されています。
追加された 著者 Pubby,

配列にデータを入力するだけです。これは有効なものですか?   する?

はい

私たちが直面する可能性のある問題は何ですか?

すべてのデータアクセスが配列の前に置かれていれば、それは多くありません。オフセットが最後から取られた場合、またはサイズを含む計算に基づいて問題が発生する可能性があります。

値が大きすぎるように思えるだけです。いずれかがあります   この必要性を回避するより良い方法は?

より良い方法がありますが、そのサイズのせいではありません。 STL容器は素晴らしい考えです。実行時に現在の必要性に応じて std :: vector をサイズ変更することができます。

0
追加された
std :: vectorを使用している場合、OPが明示的に使用しないと言った動的メモリを使用している場合、スタック(または静的メモリセグメント)に配列を割り当てたいと考えます。 std :: vectorはヒープを使います。
追加された 著者 Lundin,
うん、私のコメントを投稿した後、これに気づいた。
追加された 著者 Lundin,
@ランディンそれは質問のバージョン1が言ったものではありません。そして私は元の質問に提案としてstlで答えました。
追加された 著者 Joe McGrath,