Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C语言中声明一个非常大的三维数组?_C_Multidimensional Array_Initialization_Out Of Memory - Fatal编程技术网

如何在C语言中声明一个非常大的三维数组?

如何在C语言中声明一个非常大的三维数组?,c,multidimensional-array,initialization,out-of-memory,C,Multidimensional Array,Initialization,Out Of Memory,我正在尝试创建一个三维数组S[][] 当尺寸较小时,例如: m=40; int S[m][m][m]; memset(S, 0, sizeof(S[1][1][1])*m * m * m); //initialize all the array with 0// for (i=1 ; i<=m ; i++ ) { k=1; for (j=1 ; j<=n ; j++ ) { if(statement) { //if s

我正在尝试创建一个三维数组S[][]

当尺寸较小时,例如:

  m=40;  
  int S[m][m][m];
  memset(S, 0, sizeof(S[1][1][1])*m * m * m);  //initialize all the array with 0//
  for (i=1 ; i<=m ; i++ )  { 
      k=1;
     for (j=1 ; j<=n ; j++ ) {
       if(statement) {   //if statment true i put in S array a value//
       S[i][i][k]=j;    k++;}
  m=1500;
  int S[m][m][m];
  memset(S, 0, sizeof(S[1][1][1])*m * m * m);
  ....
  ....
我的程序可能停止工作,可能是因为内存使用,或者类似的,我不知道…知道吗


谢谢。

您必须动态分配这么大的阵列。这里有一个方法:

m = 1500;
int (*S)[m][m] = calloc( m, sizeof *S );
if ( !S )
{
  fprintf( stderr, “Fatal: unable to allocate array\n” );
  exit( EXIT_FAILURE );
}

for ( i = 0; i < m; i++ )
{
  k = 0;
  for ( j = 0; j < m; j++ )
  {
    if ( expr )
    {
      S[i][i][k++] = j;
    }
  }
}

free( S );
S
指向
int**
的1500个元素序列1;每个
S[i]
都指向
int*
的1500个元素序列;每个
S[i][j]
都指向
int
的1500个元素序列

优点-没有一块内存那么大(5到10KB,取决于指针大小)

缺点-行在内存中不是相邻的,因此不能用一个指针“遍历”整个数组,也不能在单个
memcpy
fwrite
调用中复制或序列化数组

如果出现故障,请小心回滚任何部分分配-仅释放
S
不会释放为每个
S[i]
S[i][j]
分配的内存

完成后,需要按与分配相反的顺序取消分配:

// free in reverse order of allocation
for ( i = 0; i < m; i++ )
{
  for ( j = 0; j < m; j++ )
    free( S[i][j] );
  free( S[i] );
}
free( S );
//按与分配相反的顺序释放
对于(i=0;i
同样,这假设您的系统可以支持16 GB以上的虚拟地址空间(即64位)。如果没有,你将无法建造这么大的建筑


  • 我有意在这里使用术语“序列”而不是“数组”,因为
    S
    S[I]
    、以及
    S[I][j]
    都不是这样的数组。这些项中的每一项都是指针,而不是数组。
    您的代码存在多个问题:

    您的数组是可变长度数组。这意味着数组最有可能在堆栈上分配,而堆栈的大小是有限的(在linux上,默认值是8192kib,如果这是使用的系统)。假设
    sizeof(int)==4
    , 当
    m=128
    时,此空间将耗尽。对于
    m>=128
    您将得到一个分段错误,因为访问的内存区域超出堆栈的边界,因此(很可能)将访问未分配堆内存的地址

    内存消耗 对于
    m=128
    ,阵列将消耗8个MiB,考虑到即使是普通的32位操作系统也应能够处理总共4GB的内存,该MiB并不是那么大。但是内存消耗以3的幂增长。对于
    m=1500
    ,总共将使用~12.6Gib(精确地说是1.35e10字节)。这远远超出了
    堆栈的大小,如果在堆上分配内存,甚至可能导致问题。上面提到的32位系统作为一个例子,将在此基础上阻塞(忽略PAE等特殊情况)

    总结
    如果您想为
    m
    支持127以外的值,则必须在堆上分配内存。这将推动限制以匹配所提供系统可处理的内存大小。以上所有计算都是粗略估计,不考虑特殊情况,也不应按字面计算。他们应该这样做,以便对可以处理的上限有一个印象。

    m=1500;整数S[m][m][m]对于堆栈来说太大。使用
    malloc
    ;i
    i=0;i
    int(*S)[m][m]=malloc(m*sizeof*S)您也在索引数组的边界。C中的数组索引是从零开始的,所以在您的例子中是从0到m-1。您需要在执行任何其他操作之前修复该问题。
    memset(S,0,sizeof(S[1][1][1])*m*m*m)->
    memset(S,0,sizeof S)谢谢,但是当你的意思是如果(!S){//内存分配失败,在这里退出}然后使用S?在S数组中,使用for,我给出这样的值。。。S[1][1][1]=2,。。。[1][1][2]=8。。。如果一个状态为false,它将停止(例如,直到S[1][1][8]=x,然后继续到S[2][2][1]…到S[m][m][1]…我如何使用你说的这个方法?我不知道是否可能(从StackOverFlow系统)若要将代码作为评论发布在此处,以100%理解我的问题,@NakosKotsanis:代码是正确的,并回答了标题中的问题。如果您有不同的问题,请阅读并提出新问题。我确信代码是正确的,但我真的不明白如何使用@JohnBobe所说的代码…除了标题之外,我不知道如何使用它这是一个解释问题的描述。如果因为我不知道如何在我的案件中使用它,所以我向John询问更多细节的事实是被禁止的,那么为什么会有“描述字段”以及回答更多细节的可能性?…无论如何,你知道的更好;)@NakosKotsanis:在“if”语句的主体中,您将记录一个错误并返回(因此称为“bail out”);代码的其余部分仅在分配成功时执行。
    
    
       int ***       int **               int *                   int 
      +---+         +---+                +---+                   +---+
    S:|   | ------> |   | S[0]   ------> |   | S[0][0] --------> |   | S[0][0][0]
      +---+         +---+                +---+                   +---+
                    |   | S[1]           |   | S[0][1]           |   | S[0][0][1]
                    +---+                +---+                   +---+
                     ...                  ...                     ...
                    +---+                +---+                   +---+
                    |   | S[m-1]         |   | S[0][m-1]         |   | S[0][0][m-1]
                    +---+                +---+                   +---+
    
    // free in reverse order of allocation
    for ( i = 0; i < m; i++ )
    {
      for ( j = 0; j < m; j++ )
        free( S[i][j] );
      free( S[i] );
    }
    free( S );