1

行列乗算プログラムを作成していて、コードスペースを節約するためmakeに、ダブルポインターへのポインターを受け取り、指定されたサイズの2次元配列を動的に割り当てる関数を作成しました。配列abは、[-2、2]のランダムな値に初期化されます。ただし、gccでコードを実行しようとすると、セグメンテーション違反が発生します。

b[0][0]gdbを介してコードを実行しましたが、乱数に設定しようとするとエラーが発生します。b[0][0]gdbで印刷しようとすると、次のエラーが発生します。

アドレス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;
}
4

3 に答える 3

5

1つの問題は、の呼び出しfree(tmp)ですmake。これが、アレイに割り当てられたメモリです。引き続き使用する場合は、解放しないでください。

于 2012-12-18T15:27:42.653 に答える
0

「2D配列になる」のすべての行にメモリを割り当てる必要があります。最初の行にのみメモリを割り当ててから、すべてのポインタが同じデータにポイントするようにします。これは意味がありません。

最初のmalloc呼び出しが成功したかどうかはチェックしません。

この関数からfreeを呼び出すべきではありません。

ポインタ間の混乱ではなく、隣接して割り当てられたメモリセルを使用して真の2D配列を作成するのが常に最善です。

于 2012-12-18T15:41:36.903 に答える
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;
}
于 2013-03-10T04:37:22.200 に答える