我有一个 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/