配列型とmallocで確保された配列の違い
疑問点
今日、私は友人のCコードを手伝っていたのですが、いくつかの奇妙な動作を発見し、それがなぜ起こっているのか彼に説明することができませんでした。私たちは整数のリストを含むTSVファイルを持っていて、その中に
int
という行があります。最初の行はリストが持っている行数でした。
また、非常に単純な "readfile" を持つ c ファイルがありました。最初の行は、読み込まれた
n
という初期化、行数の指定がありました。
int list[n]
で、最後にforループで
n
というループで
fscanf
.
小さな n (~100.000 まで) では、すべてがうまくいきました。しかし、n が大きいとき (10^6) には、セグメンテーション フォルトが発生することがわかりました。
最後に、私たちはリストの初期化を
int *list = malloc(n*sizeof(int))
で、うまくいくと、非常に大きな
n
.
なぜこのようなことが起こったのか、誰か説明してください。
int list[n]
を使用し始めると停止しました。
list = malloc(n*sizeof(int))
?
どのように解決するのですか?
ここでは、いくつかの異なる要素が絡み合っています。
1つ目は、配列を
int array[n];
と
int* array = malloc(n * sizeof(int));
最初のバージョンでは、自動保存期間を持つオブジェクトを宣言しています。 これは、配列を呼び出す関数が存在する限り、配列が生き続けることを意味します。 2番目のバージョンでは、動的な保存期間を持つメモリを取得しています。
free
.
ここで2番目のバージョンが動作する理由は、Cが通常どのようにコンパイルされるかの実装の詳細です。 通常、C 言語のメモリは、スタック (関数呼び出しとローカル変数用) とヒープ (関数呼び出しとローカル変数用) を含むいくつかの領域に分割されます。
malloc
オブジェクト)。 スタックは通常、ヒープよりもはるかに小さいサイズであり、通常は8MBといったところです。 その結果、巨大な配列を
int array[n];
そうすると、スタックの記憶領域を超えてしまい、セグメンテーションフォールトが発生する可能性があります。 一方、ヒープは通常巨大なサイズ(例えば、システム上で空いているスペースと同じだけ)を持っていますので
malloc
を使用してもメモリ不足のエラーは発生しません。
一般に、C言語では可変長配列には注意が必要です。
を使うようにしましょう。
これが役に立つといいのですが。
関連
-
C: 1を求める! + 2! + 3! + ... + n! (ループ)
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] 新しい配列を作成せずに、既存のJavaScript配列を別の配列で拡張する方法
-
[解決済み] JavaScriptで2つの配列の差を取得する方法は?
-
[解決済み] Cプリプロセッサはなぜ "linux "という単語を定数 "1 "と解釈するのですか?
-
[解決済み] ++iとi++の違いは何ですか?
-
[解決済み] JavaScriptの配列宣言で「Array()」と「[]」はどう違うのですか?
-
[解決済み] mallocとcallocの違い?
-
[解決済み】定義と宣言の違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[C] レポートエラー 代入の左オペランドとしてlvalueが必要
-
警告:代入がキャストなしで整数からポインタを作成する場合の修正方法に関する警告
-
[解決済み] C++で配列の最大長制限はありますか?
-
initializer element is not constant "というエラーが表示されるのですが?
-
[解決済み] Valgrind が初期化されていないバイトについて警告する
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] while ( !feof (file) ) 」は、なぜいつも間違っているのですか?
-
[解決済み] longをフォーマットするprintfの引数は何ですか?
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み] C 言語の配列へのポインタ/ポインタの配列の曖昧さ解消