【问题标题】:Why does this C code yields a double free or corruption? [duplicate]为什么这个 C 代码会产生双重释放或损坏? [复制]
【发布时间】:2016-01-10 01:41:46
【问题描述】:

为什么这个用于计算两个向量的内积的代码在编译时会产生双重释放或损坏错误:

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

代码来自this reference

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

【问题讨论】:

标签: c memory-corruption double-free


【解决方案1】:

错误是因为传递给free() 的值与malloc() 返回的值不同,因为您递增aabb

要更正它,例如,您可以定义两个仅用于内存管理的附加指针变量,即分配和释放。一旦他们获得内存,将其分配给aabb

【讨论】:

  • 更好的方法是对 malloc 进行一次调用,对 free 进行一次调用。 aa 和 bb 的内存可以在一个块中。这是一个微优化,但它可以提高内存并且减少两次库调用。
【解决方案2】:

你可以简化:

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

这具有双重好处,即避免增加导致问题的指针,并使代码更清晰。

【讨论】:

  • 为了使对称性更加清晰,我可能会使用sum0 += aa[ii * 2 + 0] * bb[ii * 2+ 0]; sum1 += aa[ii * 2 + 1] * bb[ii * 2 + 1];,因为我知道即使是关闭优化的最愚蠢的编译器也不太可能实际添加 0。请注意 sum 变量的重命名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 2021-04-06
相关资源
最近更新 更多