【问题标题】:Dynamically allocated array - elements not accessible动态分配的数组 - 元素不可访问
【发布时间】:2012-12-18 15:25:34
【问题描述】:

我正在编写一个矩阵乘法程序,为了节省代码空间,我创建了一个函数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;
}

【问题讨论】:

  • 除了 Mark Wilkins 在下面诊断出的主要问题之外,请注意 make 中的 if (a == NULL) 块没有任何好处,因为您在函数的前面已取消引用 a。您应该删除该代码块或将其移动到立即分配 a

标签: c pointers multidimensional-array


【解决方案1】:

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

【讨论】:

  • 第二双眼睛有时会有所帮助!请注意,为避免泄漏,在某些时候仍需要释放该内存。由于它的基地址被分配给 a[0],因此您可以将其用作 free 的指针(在释放 a 之前)。或者,您可以(使用更复杂的指针数学)将整个数组分配为一大块而不是两次分配。
【解决方案2】:

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

你不检查第一次 malloc 调用是否成功。

你不应该从这个函数中调用 free。

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

【讨论】:

    【解决方案3】:

    我已将部分代码粘贴在这里

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 2011-12-10
      • 2020-10-24
      • 2016-12-13
      • 2021-06-29
      • 2019-07-19
      • 2022-11-13
      相关资源
      最近更新 更多