0

重複の可能性:
メモリを割り当てられませんでした

私の次のコードは正常に動作します:

double weight [600] [800][3];
double mean [600] [800][3];
double sd [600] [800][3];
double u_diff [600] [800][3];

for ( int i = 0; i < 600; i ++ )
{
    for ( int j = 0; j < 800; j ++ )
    {
        for ( int k=0; k < 3; m ++ )
        {
            weight [i][j][k] = 0;
            mean[i][j][k] = 0; 
            sd[i][j][k] = 6;        
        }       
    }
}

しかし、それを次の形式に変更すると、次のようになります。

int init = 6;
int C = 3;

for ( int i = 0; i < 600; i ++ )
{
    for ( int j = 0; j < 800; j ++ )
    {
        for ( int k =0; k < 3; k ++ )
        {
            weight [i][j][k] = 1/C;
            mean[i][j][k] = rand(); 
            sd[i][j][k] = init;         
        }       
    }
}

クラッシュします。「重量」、「平均」、「sd」を別々に試してみました。次のように変更されたデータ型であるとは思えません。

double value = rand();
weight[i][j][m] = value;

しかし、エラーはまだ残っています。ここで何が問題なのですか?

4

3 に答える 3

1

Cygwin(1.7.15) と VC++ コンパイラで次のコードをビルドしようとしましたが、クラッシュしませんでした。それは私にとってはうまくいきます。

double weight [600] [800][3];
double mean [600] [800][3];
double sd [600] [800][3];
double u_diff [600] [800][3];

int init = 6;
int C = 3;
int main()
{
int i = 0; for ( i = 0; i < 600; i ++ ) {
int j = 0; for ( j = 0; j < 800; j ++ ) {
int k = 0;
for ( k=0; k < 3; k ++ ) {
weight [i][j][k] = 1/C; mean[i][j][k] = rand(); sd[i][j][k] = init; } }
}
return 0; }

于 2012-10-05T13:45:38.590 に答える
1
mean[i][j][k] = rand(); 

なにk?もしかして

mean[i][j][m] = rand(); 

?

また、両方ともsであるため、 1/Cforは 0 です。おそらくあなたが欲しかったですか?C=3int1.0/C

編集とコメントの後の回答:

これらの配列はかなり巨大です。それらを動的に割り当てる必要があります。

double* mean = new double[600*800*3];
// in the inner loop:
    mean[ k + 800*( j + 600*i )] = rand();

// when you're done with them
delete[] mean;
于 2012-10-05T13:00:23.757 に答える
1

クラッシュする最初のバージョン (cygwin、4.5.3) も取得しました。

この問題は、スタック サイズが約 2 MB に制限されていることに関係しています。

クラッシュしない理由は、おそらく最適化
によるものです。他のフラグメントの「rand」が原因で、オプティマイザー/コンパイラーは
、配列がまったく使用されていないことを認識できなかった可能性があります
。断片。

gcc -std=c99 tst.c -O  && ./a.exe -- produces nothing
gcc -std=c99 tst.c && ./a.exe -- segmentation fault

エラーを回避するには、malloc を使用してヒープから大きな配列を割り当てます (または、かなり小さい配列 80x60x3 を使用して制限を調べます)。

// tst.c
// compile and run with gcc -std=c99 tst.c -DOK=0 -DW=80 -DH=60 && ./a.exe    // ok
//               or     gcc -std=c99 tst.c -DOK=0 -DW=800 -DH=600 && ./a.exe  // crash
//               or     gcc -std=c99 tst.c -DOK=1 -DW=800 -DH=600 && ./a.exe  // ok
#include <stdlib.h>
int main()
{
#if OK
    double *weight =(double*)malloc(W*H*3*sizeof(double));      // no crash
#else
    double weight[W*H*3];   // crash when W*H is large, nocrash when W*H is small
#endif
    int z=0;
    for ( int i = 0; i < W; i ++ )
    {
        for ( int j = 0; j < H; j ++ )
        {
            for ( int m =0; m < 3; m ++ )
            {
                 weight[z++]=0;     
            }       
        }
    }
    return 0;
}
于 2012-10-05T13:04:00.907 に答える