質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

602閲覧

c言語での大きな領域の確保

anpapa

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2018/10/25 08:01

編集2018/10/26 11:57

c言語で書かれたプログラムがあり、Nの値に合わせて様々な処理を行うのですが、Nの値がある大きさ以上になると、セグメンテーション違反が出てしまい実行できません。

その対策として、コンパイルする際にオプション-mcmodel=mediumをつけるとうまくできていたのですが、N=55000以上になるとまたエラーが出てしまいます。

最大でNを150000まで増やす予定なのですが、どうすればよろしいでしょうか。

また、不明な点や必要な情報がありましたらお聞きください。宜しくお願い致します。

追記2018/10/26
様々なアドバイスどうもありがとうございます。
ttyp03さんに計算していただき96GBはかなり無駄が多いと感じ、プログラムの構造を考え直していました。

何名かの方も指摘してくださっていますが、なぜそんなに配列が必要かというと
まず、三次元のデータが150000個あります。
それぞれの点の距離を計算し、ある半径内に含まれる点のペアを作成し、それらの距離を規格化し次の処理を行います。
その際に、それぞれの距離を格納しておくためにNの二乗分の配列が必要になっています。

C

1N =55000以上でエラー 2 3double a[N][N]; 4double b[N][N][3]; 5double c[N]; 6 7int d[N][6]; 8int e[N]; 9int f[N]; 10int g[N]; 11 12double h[N][3]; 13double i[N][3]; 14double j[N][3]; 15. 16. 17. 18.

ヘッダファイルは最初のmain関数でのみ呼び出しており、複数回読み込んではいませんでした。

配列数 doubleの数 12100550000 intの数 495000 double及びintの数 12101045000 double a[N][N];(3025000000) double b[N][N][3];(9075000000) double c[N];(55000) int d[N][6];(330000) int e[N];(55000) int f[N];(55000) int g[N];(55000) double h[N][3];(165000) double i[N][3];(165000) double j[N][3];(165000)

gdbで確認してみると、以下のようなメッセージが出ています。

gdb

1During startup program terminated with signal SIGSEGV, Segmentation fault.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2018/10/25 08:04

それらの配列変数は、関数の中にありますか、それとも外ですか?
anpapa

2018/10/25 08:06

ご指摘どうもありがとうございます。ヘッダファイルの中にあるので、関数の外にあります。
dice142

2018/10/25 08:08

「これ以上」に関して具体的な数値がないようですが、質問は「上限がどこまで」というものなのか「ある値以上まで増やすには」というものなのか、どちらでしょう?
anpapa

2018/10/25 08:10

失礼しました、質問文を訂正いたします。そちらと質問は、ある値以上まで増やすにはというものです。
guest

回答5

0

ベストアンサー

サイズ計算してみました?

N=55000
double a[N][N];
double b[N][N][3];
double c[N];

a=8*55000*55000 =24,200,000,000=24GB b=8*55000*55000*3=72,600,000,000=72GB c=8*55000 =440,000 =440KB

cはたいしたこと無いので除外して、aとbだけで96GB必要です。
55000未満ならOKということでグローバル変数か静的変数にはなっていると思われそこは良いのですが、さすがに96GBは何かあってもおかしくないのでは・・・。
(すみません、具体的に何が起こるかはわかりません)

まず処理的に無理があるので全てをメモリに持たなくても済む方法を考えたほうがいいですね。
96GB(最終的にはもっと)はメモリ確保できたとしても仮想メモリを使っているはずですから、相当処理が重そうです。
物理的にメモリがそれだけ載っているなら話は別ですが。

投稿2018/10/25 08:35

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

回答では有りません。
まず、なぜそんな大きな領域がいるのか考えましか?
そして、それは本当に必要なのでしょうか?

・・・エラトステネスの篩で、100億まで算出しても10G程度です。

投稿2018/10/26 09:58

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ヘッダファイルの中にあるって、もしかしてそのヘッダファイル、複数のソースからインクルードされて、無意味に多重に領域使ったりしてないですか?

で、それらの配列のサイズが全体でどれだけになるか計算してみましょう。
それで、どれだけ使うとエラーになるのかをはっきりさせましょう

投稿2018/10/25 08:11

編集2018/10/25 08:13
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anpapa

2018/10/25 08:37

ありがとうございます、計算してみます。 そちらと、ヘッダファイルについてですが、ヘッダファイルは最初のmain関数でのみ呼び出しており、複数回読み込んではいませんでした。
guest

0

結論から言うとそんなバカでかいメモリをstatic storageに割り当てるとか正気ではないので動的確保しましょう。また例えばWindowsだと一度に2GBを超える動的確保はやはり失敗しやすいので、小分けにして上げるなどしましょう。

投稿2018/10/26 07:09

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ttyp03さんの計算結果を借用すると、96GB 以上必要という事です。
ちょっと Windos10での ページファイルサイズがどうなっているか調べてみたところ、 64 ビット版の Windows に適したページ ファイルのサイズを決定する方法 なんてページがありました。
ここの記述によると、

RAM の 3 倍と 4 GB のいずれか大きな方 これは、ボリュームサイズ ÷8 に制限されます。

という記述があります。この制限に引っ掛かっている可能性はないでしょうか? Linuxとかだと、ちょっと違うかも知れませんが、多分、同様の制限があると思います。

あっ、gdb上で動かした場合と言う事? それともgdb無しでも同じでしょうか。gdbで動かした時、エラー発生アドレスとか無いでしょうか?

投稿2018/10/25 12:16

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問