在MPI_Recv写入数组后释放数组

时间:2014-01-20 10:44:35

标签: c malloc mpi free

我有一个malloc'd整数数组,我用MPI_Recv

填充
MPI_Recv(d.current, n, MPI_INT, 0, TAG_CURRENT_ARRAY, MPI_COMM_WORLD, &status);

我在d.current之前和之后测试了MPI_Recv的值,但它没有改变(这是正确的)。

我的数据正确到达。

但是,如果我尝试free数据,我会收到错误:

*** Error in `./bin/obddhe-mpi': free(): invalid next size (fast): 0x0965e988 ***

在接收完美之前完全相同的免费。

...即 这个作品:

free(d.current);
//MPI_Recv(d.current, n, MPI_INT, 0, TAG_CURRENT_ARRAY, MPI_COMM_WORLD, &status);

这失败了:

MPI_Recv(d.current, n, MPI_INT, 0, TAG_CURRENT_ARRAY, MPI_COMM_WORLD, &status);
free(d.current);

MPI_Recv可以做什么使免费无效!?

1 个答案:

答案 0 :(得分:5)

SSCCE会非常有用。

那就是说,我会尽力回答:

  

我有一个malloc'd整数数组,我用MPI_Recv填充

MPI_Recv(d.current, n, MPI_INT, 0, TAG_CURRENT_ARRAY, MPI_COMM_WORLD, &status);

那个阵列有多大?你究竟是如何malloc()的?在这种情况下n是什么?它与malloc() ed尺寸有什么关系?

您的观察结果显示MPI_Recv()是发生此错误的原因。为了发生此错误,MPI_Recv()已写入malloc()内存区域的末尾,不允许这样做。这会使内存管理内部使用的链表或其后面的块大小或两者混乱,从而导致上述错误。

  

我在MPI_Recv之前和之后测试了d.current的值,它没有改变(这是正确的)。

(应该如何?你将指针传递给函数,而不是它的地址。所以指针不能改变。)

  

但是,如果我尝试释放数据,我会收到错误:

     
    

*`./bin/obddhe-mpi'出错:free():下一个大小无效(快):0x0965e988 *

  
     

在接收完美之前完全相同的免费。

这是我上面写的内容的另一条线索:你使用的块后面的meory已被释放并包含指向下一个空闲区域的指针。如果你free()你的内存,库试图合并空闲块,其中第二个被破坏,导致这个错误。

想象一下你有以下情况:

  • 您的内存管理器会根据其长度预先设置每个内存块,无论是空闲还是已分配。
  • 空闲块在开始时具有下一个空闲块的地址 - 这是我提到的链接列表。
  • 您分配的块前面有它的长度,后跟
    • 一个空闲块,前面有它的长度,如果没有下一个空闲块,则包含下一个空闲块的地址。

然后,如果你写过你的记忆块的末尾,下一个块的长度和内容将被触及并被篡改。

这对任何事都没有影响 - 直到现在。

但是如果您在块上调用free(),则此块将与之后的空闲块合并。

为此,必须执行以下操作:

  • 遍历链表以查找相邻的空闲块 - 这可能导致此错误,因为第二个空闲块的“下一个”指针是垃圾。
  • 计算其他块中较大空闲块的大小。如果其中一个包含垃圾,垃圾将用于计算新的,更大的空闲块大小,并且混乱是完美的。