c - 在 MPI_Recv 写入后释放数组

标签 c malloc mpi free

我有一个 malloc 的整数数组,我用 MPI_Recv 填充它

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

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

我的数据正确到达。

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

*** 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 会做什么使免费无效!?

最佳答案

A SSCCE会很有帮助。

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

I have a malloc'd array of integers that I fill with 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()ed 内存区域的末尾,这是不允许的。这会弄乱内存管理内部使用的链表或它后面的 block 的大小或两者,从而导致上述错误。

I have tested the value of d.current both before and after the MPI_Recv and it doesn't change (which is correct).

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

However if I try to free the data I get an error:

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

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

这是我上面所写的另一条线索:您使用的 block 背后的内存已被释放,并包含指向下一个空闲区域的指针。如果您 free() 您的内存,库会尝试合并空闲 block ,其中第二个 block 已损坏,从而导致此错误。

假设您遇到以下情况:

  • 您的内存管理器会在每个内存块(无论是空闲的还是已分配的)前添加其长度。
  • 空闲 block 的开头有下一个空闲 block 的地址——这就是我提到的链表。
  • 你分配的 block ,前面加上它的长度,后面是
    • 一个空闲 block ,前面加上它的长度,如果没有下一个空闲 block ,则包含 NULL 的下一个空闲 block 的地址。

然后,如果您写入超过内存块的末尾,下一个 block 的长度和内容将被触及和篡改。

这不会影响任何东西 - 直到现在。

但是如果你在你的 block 上调用free(),这个 block 将与它后面的空闲 block 合并。

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

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

关于c - 在 MPI_Recv 写入后释放数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21231852/

相关文章:

c - 在内核 4.14 中使用 'MSG_ZEROCOPY' 标志和 'SO_ZEROCOPY' 选项发送 buf 的行为比 non_zerocpy 更糟糕

malloc - char* malloc 的 strlen

c - 取消引用数组名称

JAVA循环问题

c - MPI 笛卡尔拓扑 - MPI_Gather 等效吗?

c - C 中的二项式系数

c - 无法重新连接到 ODBC 连接

c - Glade 3.18.3 的 Windows 二进制文件?

c - malloc ,如何在函数中自由返回值

c - 为什么在函数内部调用时 malloc 返回空指针?