2

2 つのベクトルの内積を計算するためのこのコードをコンパイルすると、二重解放エラーまたは破損エラーが発生するのはなぜですか。

ejspeiro@Eduardo-Alienware-14:~/Dropbox/HPC-Practices$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4

コードはこの参照から来ています。

// Computation of the inner product of vectors aa and bb.

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

int main() {

  size_t nn = 100000000;
  size_t total_mem_array = nn*sizeof(double);

  double *aa;
  double *bb;
  double ss = 0.0;

  aa = (double *) malloc(total_mem_array);
  bb = (double *) malloc(total_mem_array);

  int ii = 0;

  for (ii = 0; ii < nn; ++ii) {
    aa[ii] = 1.0;
    bb[ii] = 1.0;
  }

  double sum1 = 0.0;
  double sum2 = 0.0;

  for (ii = 0; ii < nn/2 - 1; ++ii) {
    sum1 += (*(aa + 0))*(*(bb + 0));
    sum2 += (*(aa + 1))*(*(bb + 1));
    aa += 2;
    bb += 2;
  }
  ss = sum1 + sum2;

  free(aa);
  free(bb);

  return 0;
}
4

2 に答える 2

6

と をインクリメントすると、に渡されるfree()値が によって返される値と異なるため、エラーが発生します。malloc()aabb

これを修正するには、たとえば、メモリ管理のみに使用される 2 つの追加のポインター変数 (割り当てと解放) を定義することができます。aaそれらによってメモリが取得されたら、それをとに割り当てbbます。

于 2016-01-10T01:49:28.913 に答える
0

以下を簡素化できます。

for (ii = 0; ii < nn/2 - 1; ++ii) {
    sum1 += (*(aa + 0))*(*(bb + 0));
    sum2 += (*(aa + 1))*(*(bb + 1));
    aa += 2;
    bb += 2;
}

に:

for (ii = 0; ii < nn/2 - 1; ++ii) {
    sum1 += aa[ii * 2]     * bb[ii * 2];
    sum2 += aa[ii * 2 + 1] * bb[ii * 2 + 1];
}

これには、問題の原因となるポインターのインクリメントを回避し、コードをより明確にするという二重の利点があります。

于 2016-01-10T02:32:15.503 に答える