2012-08-25 25 views
5
私は例えばのように、コンパイル時に私のCプログラム内のすべての変数を宣言したい

最大BSSのサイズとデータ

質問がある
char cache[CACHE_SIZE]; 
char udp_ring[MAX_UDP_PACKET_SIZE*MAX_REQUESTS]; 
int num_packets; 
char error_codes[NUM_ERRORS][MAX_ERROR_STRING]= { 
    {"Unknown user\n"}, 
    {"Wrong password\n"}, 
    .... 
}; 

、変数のサイズが上の任意の限界があります彼らはBSSまたはデータセグメントに入るCプログラム? たとえば、8GBのRAMのCACHE_SIZEを宣言すると、動作しますか? 32ビットまたは64ビットに違いはありますか?私はLinux上でプログラムを実行する予定で、RLIMIT_DATA設定に制限はありません。

+0

"コンパイル時にCプログラムのすべての変数を宣言したい" - 実行時に宣言する方法がありますか? –

+0

はい、私はglibcにリンクしたくないので、malloc()を避ける必要があります – Nulik

+2

** sigh ** - 変数を宣言するのはあなたの考えではありません。実行時に変数を宣言することはできません。 Cブックを手に入れよう。 –

答えて

3

カーネルが処理できるように仮想メモリを管理することができます。これはアーキテクチャに依存します。

たとえば、x86アーキテクチャ(x86-64ロングモードなし)では、Linuxはプロセスによって3GB、カーネルで1GBの仮想メモリをデフォルトで分割します(PAEが有効な場合でも)。プロセスは3GB以上の仮想メモリ(テキストセクション、データ、bss、ヒープ、スタック、共有オブジェクトなどを含む)を処理することはできません。

すべてのバッファを静的に割り当てると、プロセスの仮想アドレス空間では、起動時に8GBのバッファを使用すると32ビットアーキテクチャでこの動作が発生します。

glibcのメモリ管理機能(malloc、...)に依存したくない場合は、独自のメモリ管理ライブラリをロールして、プロセスにLD_PRELOADのトリックでそれを使用させることができますmalloc/calloc/realloc/freesbrk()を使用)の実装は、独自の要件に一致します。

+0

私が理解しているように、64ビットモードで静的に割り当てられた変数には、初期化されていない(DATA) – Nulik

+1

64ビットのアーキテクチャでは、仮想アドレス空間の2^64バイト(16エクサバイト)からカーネルに対処するために確保されたスペースを引いた値が*存在します。しかし、x86-64(AMDとIntel)の現在の実装は48ビットのアドレスビット(〜256 TBの仮想アドレス空間)に制限されていますが、この制限に達する前に物理RAMを使い果たしてしまうことは間違いありません。 IIRC Linuxでは、x86-64では1プロセスあたり128TBの仮想アドレス空間が可能です。 – strnk

2

glibcとリンクしたくない場合は、syscallssyscalls(2)のマニュアルページに記載されています)を行うためのいくつかの奇妙な方法があります。どのアプリケーションでもいくつかのシステムコールが必要です(例えば、open(2)read(2)write(2) ...)。 Glibcはまた、Cインタフェースをシステムコールに提供するためにも使用されます。 assembly howtoは、libcなしでsyscallをどのように呼び出すかについて、いくつかのアセンブリコードを直接使用して(例えば、C asm命令で)説明します。廃止された_syscall(2)のマニュアルページも参照してください。 VDSOもご覧ください。

mmap(2)munmap(2) syscallsを使用してアドレススペースを変更できます。これは、メモリの割り当てと解放のための基本的な操作です。 Glibcはそれらを使用してmallocfreeを実装します。

初期化(.dataセグメント)またはクリア(.bssセグメント)のグローバル変数または静的変数を宣言すると、動的にメモリリソースを使用できなくなります。そして初期化されたデータをたくさん持っていると、かなりのコストがかかります:ELFの実行ファイルは膨大なものになります。

しかし、本当にGlibcを避けたい理由を説明する必要があります。 Cでコーディングするときは避けるのが難しいです。dietlibcのような明るい選択肢を使うことができます。

+0

ありがとう、非常に有用な情報。私はバイナリ形式でプログラムを配布しているのでglibcを避けたいですし、異なるLinuxディストリビューションとの互換性の問題を持ちたくないです。実際には私はダイナミックアロケーションを使用しますが、それは自分のヒープ管理ルーチンを持つキャッシュの場合のみです。私は他の変数の制限を知りたがっています。 – Nulik

+0

Glibcを静的にリンクすることを検討するかもしれませんが、これは通常悪い考えです。どのようなプログラムをコーディングしているのか説明してください。無料のソフトウェア(GPLライセンスなど)にすることを検討しましたか?そして、あなたのGlibcを静的にリンクすることさえ、すべての非互換性を避けてはいけません。 Glibcのいくつかはカーネルバージョンに少し依存しています... –

関連する問題