c:封底下使用1d数组的多维数组

时间:2012-02-10 22:41:08

标签: c dynamic macros multidimensional-array

我正在尝试使用巨大的4d阵列(192 gig可用);但是进入的内容与出来的内容不匹配(请参阅下面的代码中的assert())。 (我定义的尺寸很小;但实数是:20,9000,195,120)

#define SIZE_A 1
#define SIZE_B 3
#define SIZE_C 4
#define SIZE_D 2

#define offSet(a,b,c,d) ( ((size_t) SIZE_A * SIZE_B * SIZE_C * a) + ((size_t) SIZE_B * SIZE_C * b) + ((size_t) SIZE_C * c) + d)

void xall(void)
{
int *aray = (int *) malloc( (size_t) SIZE_A * SIZE_B * SIZE_C *  SIZE_D  * sizeof(int));


int counter = 0;

    for (int a = 0; a < SIZE_A; ++a){
        for (int b = 0; b < SIZE_B; ++b){
            for (int c = 0; c < SIZE_C; ++c) {
                for (int d = 0; d < SIZE_D; ++d){
                    aray[ offSet(a,b,c,d) ] = counter++;

                }}}}


counter = 0;    
    for (int a = 0; a < SIZE_A; ++a){
        for (int b = 0; b < SIZE_B; ++b){
            for (int c = 0; c < SIZE_C; ++c) {
                for (int d = 0; d < SIZE_D; ++d){       
                    int value = aray[ offSet(a,b,c,d) ] ;
                    assert(value == counter++);

                }}}}
}

4 个答案:

答案 0 :(得分:5)

正如其他人所提到的,你的宏是错误的。修复这很好,但我建议你直接分配一个多维数组,而不是手动滚动偏移宏。看看这个例子:

#include <assert.h>
#include <stdlib.h>

#define SIZE_A 1
#define SIZE_B 3
#define SIZE_C 4
#define SIZE_D 2

int main(void)
{
  int counter = 0;
  int (*array)[SIZE_A][SIZE_B][SIZE_C][SIZE_D] = 
          malloc(sizeof(int) * SIZE_A * SIZE_B * SIZE_C *  SIZE_D);

  for (int a = 0; a < SIZE_A; ++a)
    for (int b = 0; b < SIZE_B; ++b)
      for (int c = 0; c < SIZE_C; ++c) 
        for (int d = 0; d < SIZE_D; ++d)
          (*array)[a][b][c][d] = counter++;

  counter = 0;    
  for (int a = 0; a < SIZE_A; ++a)
    for (int b = 0; b < SIZE_B; ++b)
      for (int c = 0; c < SIZE_C; ++c)
        for (int d = 0; d < SIZE_D; ++d)
        {
          int value = (*array)[a][b][c][d];
          assert(value == counter++);
        }

  return 0;
}

此示例中分配的数组的内存中布局与您的问题中的内容完全相同,但为什么不让编译器为您完成工作呢?

除了一点编辑之外 - 不要将malloc()调用的返回值强制转换为C程序。从void *的转换是隐式的,并且具有显式转换可以隐藏您将获得的隐式函数声明警告 - 例如,如果您忘记包含stdlib.h

答案 1 :(得分:1)

你的宏不太正确。将其更改为:

#define offSet(a,b,c,d) ( ((size_t) SIZE_B * SIZE_C * SIZE_D * a) + ((size_t) SIZE_C * SIZE_D * b) + ((size_t) SIZE_D * c) + d)

您基本上已将SIZE_X转移了1个字母。

我还建议在您的宏参数周围添加()

#define offSet(a,b,c,d) ( ((size_t) SIZE_B * SIZE_C * SIZE_D * (a)) + ((size_t) SIZE_C * SIZE_D * (b)) + ((size_t) SIZE_D * (c)) + (d) )

答案 2 :(得分:0)

我似乎应该用这种方式定义宏:

#define offSet(a,b,c,d) ( ((size_t)  SIZE_B * SIZE_C *SIZE_D * a) + ((size_t)  SIZE_C *SIZE_D * b) + ((size_t) SSIZE_D * c) + d)

答案 3 :(得分:0)

在某些操作系统中,每个进程的内存分配限制。通常可以更改默认值。

其他人,甚至在调用malloc时都不会分配实际的内存,例如Linux,你可能会在以后尝试写入时失败,但我想这不是你的情况。

尝试检查是否可以控制系统上每个进程的最大内存分配。 希望你找到答案,这确实很有意思。

一些阅读材料:

http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory http://www.linux-mag.com/id/827/