【问题标题】:why it crashes when assigning new values to arrays? [duplicate]为什么在为数组分配新值时会崩溃? [复制]
【发布时间】:2012-10-05 12:58:08
【问题描述】:

可能重复:
Could not allocate memory

我的以下代码运行良好:

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;         
        }       
    }
}

它崩溃了。我什至尝试分别为“weight”、“mean”和“sd”工作。我怀疑它可能是数据类型,更改为:

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

但错误仍然存​​在。这里有什么问题?

【问题讨论】:

  • 平均[i][j][k] = rand();这看起来很可疑
  • 更多上下文会有所帮助。你能生成一个完整的最小程序来演示这个错误吗?见sscce.org
  • 尝试更正循环定义中的所有临时变量。还尝试在赋值循环内设置断点。至少这将有助于找出导致程序崩溃的原因。

标签: c++ arrays visual-c++ for-loop set


【解决方案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;
}

【讨论】:

  • 我根据你的回答尝试了,使用malloc,但它仍然在循环中崩溃。
  • 我也尝试了 80x60x3 尺寸,但它仍然崩溃。似乎这个错误不仅仅是堆栈溢出。
  • 您是否为较小的数组分别修改了循环大小?
  • 是的,我做了,我也改变了所有的数组,不仅仅是重量。
  • 即使是 80x60x3 x 8bytes 也需要 115200 字节,您的系统仍有可能有低于 256k 的堆栈限制。
【解决方案2】:
mean[i][j][k] = rand(); 

k 是什么?你是说

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

?

另外,C=31/C 为 0,因为它们都是 ints。也许你想要1.0/C

编辑和cmets后回答

这些数组非常庞大。您应该动态分配它们。

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;

【讨论】:

  • 是的,它是“k”,我编辑了它。我一个接一个地尝试了它们,但它仍然崩溃。即使我删除了“重量”和“平均”以保留“sd[i][j][k] = init”,错误仍然存​​在。
【解决方案3】:

我尝试在 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 &lt; 600; i ++ ) {
int j = 0; for ( j = 0; j &lt; 800; j ++ ) {
int k = 0;
for ( k=0; k &lt; 3; k ++ ) {
weight [i][j][k] = 1/C; mean[i][j][k] = rand(); sd[i][j][k] = init; } }
}
return 0; }

【讨论】:

    猜你喜欢
    • 2012-09-27
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 2011-04-17
    • 2021-05-23
    • 1970-01-01
    相关资源
    最近更新 更多