0

これは、サイズ引数を受け取り、そのサイズの整数の配列を割り当てる単純なC++プログラムです。プログラムは、32ビットアーキテクチャの仮想マシンで実行されているLinuxでg++を使用してコンパイルされます。1073741823 *を超える引数(配列サイズ)でアプリケーションを呼び出すと、

セグメンテーション違反(コアダンプ)

エラーが発生し、取得した値よりもわずかに小さい値になります。

'std :: bad_alloc'のインスタンスをスローした後に呼び出された終了
what():std :: bad_alloc中止(コアダンプ)

コードは次のとおりです。

/* dynamicAlloc.cpp */
#include <iostream> 
#include <stdlib.h> //for atoi
#include <cstdlib> // for rand() and srand()
#include <ctime> // for time()

using namespace std;
#define STR_LEN 256

int main(int argc, char* argv[])
{
    srand(time(0)); 

    unsigned int iArraySize = 1;
    if(argc < 2)
        return -1;

    iArraySize = atoi(argv[1]);

    int *pnValue = new int[iArraySize];
    if(pnValue == NULL)
    {
        cout << "cannot allocate array" << endl;
        return -2;
    }

    for(unsigned int iCounter = 0; iCounter < iArraySize; iCounter++)
    {
        pnValue[iCounter] = rand(); 
    }

    delete[] pnValue; 
    return 0;
}

2つの異なるエラーが発生するのはなぜですか?

また、数十億のデータを処理/マッサージする必要がある非常に大きなデータがある場合、そのような大量のデータを処理するためにデータベースを使用する必要がありますか、それとも大きなデータセットを処理する別の方法がありますか?

読んでくれてありがとう

* 1073741823 =(2 ^ 32(ビットアドレス))/ 4(バイト単位の整数サイズ))-1

アップデート

ulimit-aの出力は次のとおりです。

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3808
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3808
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

RAMサイズは512MBに設定されています。すべてのプログラムに独自の仮想ページがあるので(32ビットアーチの場合は4GBだと思います)、その仮想メモリをすべて使用できると思いました。

4

3 に答える 3

1

ulimit -a現在のヒープサイズをulimit -s unlimited確認してから、プログラムの動作が改善されているかどうかを確認できますか?また、仮想マシン専用のRAMはどれくらいですか?

また、なぜ32ビットのアドレス空間をすべて使用できると思いますか?カーネルやその他のものがメモリにロードされています。

于 2012-10-23T15:56:20.910 に答える
1

32ビットシステムでは、4GiBに対応できます。さらに割り当てようとすると、システムからセグメンテーション違反が発生します。4 GiB未満を割り当てるとnew、これだけ割り当てることができないため、例外がスローされます。4GiBアドレス空間のスペースを占める静的データとスタックもあります。

于 2012-10-23T16:02:45.983 に答える
1

32ビットマシンで使用できる4ギガバイトのメモリがありません。合計4ギガあります。あなたのプログラムがアクセスできるものはそれより少ないです。

不正なアドレスを作成しているため、その巨大な値のセグメンテーション違反が発生します。基盤となる機械は、そのメモリを割り当てようとする機会すらありません。割り当てを試みる前に、それは大騒ぎになります。

わずかに小さい値では、アドレスは有効ですが、何かが原因で、その大きなメモリチャンクを割り当てることができません。あなたはそれほど多くのメモリを持っていないかもしれません、あるいはあなたはあなたがそれほど多くのメモリをとることを妨げる制限を持っているかもしれません。ソフトリミットの場合は引き上げることができます。それが厳しい制限である場合、それを上げるにはシステム管理者権限が必要です。

于 2012-10-23T16:08:05.687 に答える