みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

なぜエラーになるのでしょう。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_MAX 512
#define LINE_MAX 30000

int main(void){
// ※↓がエラー原因※
char str[LINE_MAX][STR_MAX];

printf("%d\n", sizeof(int));
printf("%d\n", sizeof(int[10]));
printf("%d\n", sizeof(char[10]));
printf("%d\n", sizeof(char[STR_MAX]));
printf("%d\n", sizeof(char[LINE_MAX]));
printf("%d\n", sizeof(char[LINE_MAX][STR_MAX]));
printf("%d\n", sizeof(long[STR_MAX][LINE_MAX]));
printf("%d\n", sizeof(str));
return 1;
}
というプログラムを実行すると「問題が発生したため~を終了します。ご不便をかけて~」という問題が発生して終了してしまいます。
原因は、
printf("%d\n", sizeof(str));
の部分であるのですが、
char str[LINE_MAX][STR_MAX];
という宣言でメモリ使用量が大きすぎるということでしょうか?
しかし、
printf("%d\n", sizeof(char[LINE_MAX][STR_MAX]));
printf("%d\n", sizeof(long[STR_MAX][LINE_MAX]));
でも正常に実行できているのに・・・


もともとは、何万行もあるテキストファイルを配列に一度格納し、それらを編集して出力しようと思っていたのですが、毎回エラーが発生するので、調べたところ配列宣言の部分
char str[LINE_MAX][STR_MAX];
にエラーがあるということが分かったのですが、原因が分かっても理由がさっぱり分かりません。
googleで配列の上限について調べたり、仕様について調べたのですが、ほしい回答が得られず質問させてもらいました。
分かる方いましたら教えてください。

ちなみにExcelのマクロを組んだときにdim StrTemp(512, 30000) as stringと宣言して
Option Explicit

Function SampleTest()
Dim StrTemp(512, 30000) As String
Dim i, j As Integer
For i = 1 To 512
For j = 1 To 30000
StrTemp(i, j) = "SampleTest"
Next j
Next i
End Function
と処理をすることはできたので、パソコンのメモリ容量が足りないとは思えないのです。

投稿日時 - 2009-06-04 20:28:09

QNo.5017021

困ってます

質問者が選んだベストアンサー

>Excelのマクロと違ってC言語ってメモリの使用量が膨大なのですか?

C言語のメモリ使用量が膨大である、というわけではないです。
メモリ管理上、大きく分けて
1)関数内部のローカルな領域
2)上記以外
の2種類があります。厳密にいうともっとあるのかもしれませんが、
私はそこまでの知識を持ち合わせていません。

さて、上記1)2)のどちらも大きさが無限にあるわけではない、ということはおわかりと思います。
今回の場合、上記1)で確保可能な大きさを超えて(上限値は、私にはわかりません)
配列定義しようとしたために、プログラムの実行時に落ちてしまった、というわけです。

投稿日時 - 2009-06-04 21:10:09

お礼

ありがとうございます。
文法以外にも覚えることがたくさんありそうですね。
参考になりました。

投稿日時 - 2009-06-04 21:21:23

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

>Excelのマクロと違ってC言語ってメモリの使用量が膨大なのですか?

根本的な勘違いです。
”C言語”のメモリ使用量が膨大なのではありません。
”質問者様"のメモリ使用量が膨大なのです。

Windowsの場合、標準で、スタックサイズ
(自動変数等で使える領域の大きさ、
自動変数以外でも使われるので、
自動変数で使用可能なサイズはこれより小さい)
は1MByteです。

char str[LINE_MAX][STR_MAX]

の大きさを算出してみましょう。
charは1Byte , それがSTR_MAX = 512個集まったものを1単位として
LINE_MAX = 30000個で1つの塊です。

算数の問題で、全体は 1 * 512 * 30000[Byte]です。
これは1.5MByteです。
スタックの限界を超えています。
(スタックの底が抜けたなどと呼ばれます)

No.1さんの仰るように静的領域に移すべきだと思います。

どんな変数でもそうですが、
その性質(使用目的、大きさ、スコープ等)をよく考えた上で、
最適な場所に配置してください。

投稿日時 - 2009-06-04 21:15:57

お礼

ありがとうございました。
分かりやすかったです。

投稿日時 - 2009-06-04 21:22:09

ANo.1

>char str[LINE_MAX][STR_MAX];
>という宣言でメモリ使用量が大きすぎるということでしょうか?

おそらく、そういうことでしょう。
関数内部のローカルな領域で定義できる範囲を超えているものと思います。
その領域の外でその配列を定義すればよいと思います。
【方法1】static char str~; として、静的変数を定義する。
【方法2】その配列の定義そのものをmain関数の外に出して、外部変数とする。

なお、

>printf("%d\n", sizeof(char[LINE_MAX][STR_MAX]));
>printf("%d\n", sizeof(long[STR_MAX][LINE_MAX]));
>でも正常に実行できているのに・・・

これは、そういう「値を、単に」出力しているだけです。
配列の定義を実際に行なった上で出力しているわけでは「ありません」。

投稿日時 - 2009-06-04 20:42:04

お礼

ありがとうございます。
Excelのマクロと違ってC言語ってメモリの使用量が膨大なのですか?
今までマクロは普通に出来たことでしたのに、急に使えなくなり、ファイルのインプットアウトプットが扱いづらく感じていました。
C言語の方が処理が速いと聞いたからやってみたのですが、、、

低レベルな質問でしたらすみません。

投稿日時 - 2009-06-04 20:51:49