以下は、大学のタスクに対する小さなプログラムです。
#include <unistd.h>
#ifndef BUFFERSIZE
#define BUFFERSIZE 1
#endif
main()
{
char buffer[BUFFERSIZE];
int i;
int j = BUFFERSIZE;
i = read(0, buffer, BUFFERSIZE);
while (i>0)
{
write(1, buffer, i);
i = read(0, buffer, BUFFERSIZE);
}
return 0;
}
代わりに stdio.h fread および fwrite 関数を使用する代替手段があります。
良い。この両方のバージョンのプログラムを 25 の異なる値のバッファー サイズ: 1、2、4、...、2^i with i=0..30 でコンパイルしました。
これは私がそれをコンパイルする方法の例です: gcc -DBUFFERSIZE=8388608 prog_sys.c -o bin/psys.8M
質問: 私のマシン (Ubuntu Precise 64、詳細は最後に) では、プログラムのすべてのバージョンが正常に動作します: ./psys.1M < data
(データは 3 行の ASCII テキストを含む小さなファイルです。)
問題は、バッファ サイズが 8MB 以上の場合です。両方のバージョン (システム コールまたは clib 関数を使用) は、これらのバッファー サイズでクラッシュします (セグメンテーション フォールト)。
私は多くのことをテストしました。コードの最初のバージョンは次のようなものでした: (...) main() { char buffer[BUFFERSIZE]; int i;
i = read(0, buffer, BUFFERSIZE);
(...)
読み取り関数を呼び出すと、これがクラッシュします。しかし、これらのバージョンでは:
main()
{
char buffer[BUFFERSIZE]; // SEGMENTATION FAULT HERE
int i;
int j = BUFFERSIZE;
i = read(0, buffer, BUFFERSIZE);
main()
{
int j = BUFFERSIZE; // SEGMENTATION FAULT HERE
char buffer[BUFFERSIZE];
int i;
i = read(0, buffer, BUFFERSIZE);
どちらもメインの最初の行でクラッシュします (SEGFAULT)。ただし、バッファーをメインからグローバル スコープに移動すると (したがって、スタックではなくヒープに割り当てられます)、これは正常に機能します。
char buffer[BUFFERSIZE]; //NOW GLOBAL AND WORKING FINE
main()
{
int j = BUFFERSIZE;
int i;
i = read(0, buffer, BUFFERSIZE);
私は Ubuntu Precise 12.04 64 ビットと Intel i5 M 480 第 1 世代を使用しています。
#uname -a
Linux hostname 3.2.0-34-generic #53-Ubuntu SMP Thu Nov 15 10:48:16 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
スタックに関する OS の制限がわかりません。これは良い方法ではありませんが、大きなデータをスタックに割り当てる方法はありますか?