动态分配的数组 - 无法访问的元素

时间:2012-12-18 15:25:34

标签: c pointers multidimensional-array

我正在编写矩阵乘法程序,为了节省代码空间,我创建了一个函数make,它接受​​一个指向双指针的指针并动态分配给定大小的二维数组。数组ab初始化为[-2,2]中的随机值。但是,当我尝试在gcc上运行代码时,我遇到了一个seg错误。

我通过gdb运行代码,当我尝试将b[0][0]设置为随机数时出现错误。当我尝试在gdb中打印b[0][0]时,我收到错误:

  

无法访问地址0xbfebfdc3f5d77f80

的内存

但是,我实际上能够在此之前访问b[0][0]。我可以在分配它之后立即打印数组而不会出错。出于某种原因,数组b似乎总是会导致问题。

我感觉这是一个指针问题,但我看不到哪里。我不是一个没有经验的程序员,但我花了2天的时间试图找出为什么这个错误不断出现。任何人都能解释一下吗?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


void make(double ***a, int m, int n)
{
  int i;
  double *tmp;


  (*a) = (double **) malloc(m*sizeof(double *));
  tmp = (double *) calloc(m*n,sizeof(double));

  if(tmp == NULL)
  {
    printf("Error with malloc.\n");
    exit(EXIT_FAILURE);
  }

  for(i=0;i<m;i++)
    (*a)[i] = &tmp[i*n];


  free(tmp);

  if(a == NULL)
  {
    fprintf(stderr, "Error with the matrix, dimensions: %d, %d. \n", m, n);
    exit(EXIT_FAILURE);
  }
}


int main()
{
  int i, j;
  int l, m, n;
  double **a, **b, **c;

  l = m = n = 8;

  srand48(time(NULL));

  make(&a, l, m);
  make(&b, m, n);
  make(&c, l, n);

  for(i=0; i<l; i++)
    for(j=0; j<m; j++)
      a[i][j] = (drand48()*4.0) - 2.0;

  for(i=0; i<m; i++)
    for(j=0; j<n; j++)
      b[i][j] = (drand48()*4.0) - 2.0;

  free(a);
  free(b);
  free(c);

  return 0;
}

3 个答案:

答案 0 :(得分:5)

一个问题是free(tmp)中对make的调用。那是为数组分配的内存。如果您打算继续使用它,则不应释放它。

答案 1 :(得分:0)

您需要为“可能的2D数组”中的每一行分配内存,您只需为第一行分配内存,然后让每个指针指向相同的数据。这没有任何意义。

您不检查第一个malloc调用是否成功。

你不应该免费使用此功能。

最好使用相邻分配的内存单元创建true 2D array,而不是指针指针混乱。

答案 2 :(得分:0)

我已将部分代码粘贴到此处

int *nn,*kk;
int main()
{
int t=0,i;

scanf("%d",&t);
int maxx=0;
nn = new int [t];
kk = new int [t];
for(i=0;i<t;i++)
{
    scanf("%d%d",&n,&k);
    nn[i] = n;
    kk[i] = k;
    if(maxx<n)
        maxx=n;
        cout<<nn[i]<<" "<<kk[i]<<endl;
}
t=0;
for(i=0;i<t;i++)
{
    n = nn[i];
    k = kk[i];cout<<nn[i]<<" "<<kk[i]<<endl;
    //cout<<setprecision(6);
   if(k<34&&n>k)
        //cout<<a[n][k]<<endl;
        printf("%0.7lf\n",a[n][k]);
    else
        printf("0.000000\n");//cout<<"0\n";
}
delete []nn;
delete []kk;
return 0;
}