如何重新分配一个空的2d数组

时间:2018-02-27 17:12:08

标签: c arrays malloc realloc

我有一个多次调用的函数,参数n定义了n*2大小的2d数组:

void myfunc(int n){

  static int n0=0,i;
  static double **x=NULL;

  if(n>n0){ //realloc if n grows
    x=(double **)realloc(x,n*sizeof(double*)));
    for(i=0;i<n;i++){
      x[i]=(double *)realloc(x[i],2*sizeof(double))); // <--problem here
    }
    n0=n;
  }

}

在第一次通话时,**x被初始化为NULL,但x[i]未被初始化,因此第二个realloc的行为可能不正确。

在没有先使用reallocmalloc的情况下,有没有办法calloc空2d矩阵的行?

4 个答案:

答案 0 :(得分:4)

在这里,您应该使用malloc()而不是realloc(),因为您不是重新 - 在此处分配内存。

但是,如果您的代码无法知道数据是否为新数据,则应首先将其初始化为NULL,以使realloc()生效。

答案 1 :(得分:1)

我会在第一次更改函数malloc,之后更改realloc

但是,realloc的当前元素无需x。您只需将malloc用于x的新元素。

void myfunc(int n)
{
   static int n0 = 0;
   static double **x = NULL;

   if ( n > n0)
   {
      if ( x == NULL )
      {
         // Use malloc to get memory for x
         x = malloc(n*sizeof(double*));

         for( int i = 0; i < n; i++)
         {
            x[i] = malloc(2*sizeof(double));
         }
      }
      else
      {
         // Use realloc to get more memory for x.
         x = realloc(x, n*sizeof(double*));

         // Allocate memory only for the new elements of x.
         for( int i = n0; i < n; i++)
         {
            x[i] = malloc(2*sizeof(double));
         }
      }

      n0 = n;
   }
}

PS 请勿转换mallocrealloc的返回值。请参阅Specifically, what's dangerous about casting the result of malloc?以了解原因。

经过一番思考,我意识到这个功能可以简化一点。

void myfunc(int n)
{
   static int n0 = 0;
   static double **x = NULL;

   if ( n > n0)
   {
      if ( x == NULL )
      {
         // Use malloc
         x = malloc(n*sizeof(double*));
      }
      else
      {
         // Use realloc
         x = realloc(x, n*sizeof(double*));
      }

      // Use malloc for the new elements of x.
      // When n0 is 0, it will be all of them.
      for( int i = n0; i < n; i++)
      {
         x[i] = malloc(2*sizeof(double));
      }

      n0 = n;
   }
}

答案 2 :(得分:1)

void myfunc(int n){

  static int n0=0,i;
  static double **x=NULL;

  if(n>n0){
    x=realloc(x,n*sizeof(double*)));
    for(i=n0;i<n;i++){
      x[i]=malloc(2*sizeof(double)));
    }
    n0=n;
  }

}

答案 3 :(得分:1)

除了详细说明如何增加分配的各种答案之外,还可以通过调用myfunc(0)来更改代码以允许最终释放分配。

最好使用size_t进行数组大小调整。

i无需static

此函数隐藏其结果,可能返回指针?

double **myfunc(size_t n) {
  static size_t n0 = 0;
  static double **x = NULL;

  if (n > n0) {
    void *new_ptr = realloc(x, sizeof *x * n);
    if (new_ptr == NULL) {
      TBD_Code();  // Handle out-of-memory
    }
    x = new_ptr;
    for (size_t i = n0; i < n; i++) {
      x[i] = malloc(sizeof *(x[i]) * 2);
    }
    n0 = n;
  } else if (n == 0) {
    while (n0 > 0) [
      free(x[--n0]);
    }
    free(x);
    x = NULL;
  }
  return x;
}

考虑ptr = malloc(sizeof *ptr * n);使用*alloc()的风格。与ptr = malloc(sizeof (de-referenced_ptr_type) * n);

相比,编码权限,审核和维护更容易