LoginSignup
15
13

More than 5 years have passed since last update.

C/C++でグローバル変数(配列)を0以外に初期化すると実行ファイルが巨大になる罠

Last updated at Posted at 2015-03-21

初めに

C++はあまり詳しくないですが、ある現象を見つけたのでメモ程度に記事を書きます。
競技プログラミングなどで、出力ファイル制限があるジャッジ(yukicoderとか)などでは、気をつけましょうという記事です。

再現コンパイラバージョン

gcc 4.8.2/clang 3.5
(g++ -O2 -o a.out main.cpp / g++ -o a.out main.cpp)

対象のコード

これらのコードをコンパイルするだけで実行ファイルが40MBになります。

グローバル変数に対してリテラルで初期化しているだけです。

p[0]=0,p[1]=1,それ以外は0で初期化します。

実行ファイルが巨大になる例1
int p[10000000]={0,1};
int main(){
} 

p[0]=1それ以外0で初期化するのも同様です。

実行ファイルが巨大になる例2
int p[10000000]={1};
int main(){
} 

ただし、すべて0で初期化する場合は例外で、巨大な実行ファイルにならないようです。(a.outは4KBほど)

実行ファイルが巨大にならない例1
int p[10000000]={0};
int main(){
} 

回避コード

ローカル変数で宣言したり、

実行ファイルが巨大にならない例2
#include <iostream>
using namespace std;


int main(){
    int p[10000000]={1};

    cout<<p[sizeof(p)/sizeof(p[0])-1]<<endl;
} 

他にありましたら、教えてください。
h2suzukiさんにコメントでご指摘いただきました。
fillはしなくてもいいそうです。
コメント欄もぜひご覧ください。

実行ファイルが巨大にならない例3
#include <iostream>
using namespace std;

int p[10000000]={};

int main(){
    p[0] = 1
    cout<<p[sizeof(p)/sizeof(p[0])-1]<<endl;
} 

まとめ

ファイル制限のあるジャッジ/オンラインコンパイラだと、コンパイルエラー(CE)になるとおもいますが。
エラーメッセージも以下の様な感じで、ユーザーからは原因見つけるのが面倒そうな気がします。

g++: internal compiler error: File size limit exceeded (program as)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.

参考資料

「セクションとか.textとか」
http://www.ertl.jp/~takayuki/readings/info/no02.html
(診断人さんありがとうございます)

15
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13