巨大な配列の確保

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
プロコン始めた

巨大な配列の確保

#1

投稿記事 by プロコン始めた » 8年前

競技プログラミングを始めたばかりの初心者です。ある程度入力が大きくなってくると、

コード:

long long costs[1000000000]; 
のようなことがしたくなってくるのですが、頻繁にstartupルーチンの最中に落ちてしまいます。
以下は、プリムのアルゴリズムを書こうとした途中のコードです。

コード:

#include <iostream>
using namespace std;
#define MAXN 100000
#define min(a, b) ((a) < (b) ? (a) : (b))
#define abs(a) ((a) < 0 ? - (a) : (a))
#define BIGNUM 10000000000

int main(void)
{
  int N;
  static long x[MAXN];
  static long y[MAXN];
  static long d[MAXN][MAXN];
  int flag[MAXN] = {0};
  cin >> N;
  for(int i=0; i<N; i++) {
    cin >> x[i] >> y[i];
  }
  for(int i=0; i<N; i++) {
    for(int j=0; j<N; j++) {
      d[i][j] = min(abs(x[i]-x[j]), abs(y[i]-y[j]));
    }
  }
  flag[0] = 1;
  long long ans = 0;
  for(int i=1; i<N; i++) {
    long long mintemp=BIGNUM;
    long long minindex;
    for(int j=0; j<N; j++) {
      if(flag[j] == 1) {
	if(mintemp > d[i][j]) {
	  mintemp = d[i][j];
	  minindex = j;
	}
	ans += mintemp;
	flag[minindex] = 1;
      }
    }
  }
  cout << ans << endl;

  return 0;
}
こちらを

コード:

g++ D.cpp -Wall -g
のようにコンパイルし、実行したのですが、

コード:

~/p/a/a/065 $ ./a.out
fish: “./a.out” terminated by signal SIGSEGV (Address boundary error)
このようにSEGVで落ちてしまいます。
SEGVするところをgdbで確認したところ、

コード:

(gdb) run
Starting program: /home/tep/projects/atcoder/abc/065/a.out 
During startup program terminated with signal SIGSEGV, Segmentation fault.
(gdb) quit
このように出ます。このような現象は、巨大配列を静的に確保しようとした時によく発生するような気がします。staticをつけて解決できる時もあるのですが、解決できないことのほうが多いです。何かご存じの方がいらっしゃったら、助言いただけるとありがたいです。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 巨大な配列の確保

#2

投稿記事 by みけCAT » 8年前

例えば

コード:

#define MAXN 100000

static long d[MAXN][MAXN];
という宣言は、long型が4バイトだとすると4 * 100000 * 100000 ≒ 37.3 [GiB]
もの巨大な配列の宣言です。
GCJなどのローカルで実行するタイプならともかく、ソースコードをジャッジサーバーに提出して判定してもらうタイプのコンテストで、
16GBを超えるような巨大なメモリ制限は聞いたことがありません。
こんな巨大な配列の宣言が必要なくなるよう、アルゴリズムを見直すのがいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tetsupon
記事: 1
登録日時: 8年前

Re: 巨大な配列の確保

#3

投稿記事 by tetsupon » 8年前

アカウントを取りました。この質問をしたものです。
回答ありがとうございます。手元で必要なメモリの大きさを見積もるべきでした。自分が馬鹿げたことをしようとしていたのがよくわかりました。

返信

“C言語何でも質問掲示板” へ戻る