我有一个我用 MPI_Recv
MPI_Recv(d.current, n, MPI_INT, 0, TAG_CURRENT_ARRAY, MPI_COMM_WORLD, &status);
我在MPI_Recv
之前和之后都测试了d.current
的值,并且它不变(这是正确的)。
我的数据正确到达。
但是,如果我尝试 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
可以做什么使免费的!?
sscce将非常有帮助。
也就是说,我会尽力回答:
我有一个我用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内存区域的末尾,它不允许。这弄乱了内部由内存管理使用的链接列表或背后或两者的块大小,导致上述错误。
我已经在mpi_recv之前和之后都测试了d.urrent的值,并且它不更改(这是正确的)。
(应该如何?您正在将指针传递给功能,而不是其地址。
但是,如果我尝试释放数据,我会遇到错误:
*错误中的错误。
在接收完美工作之前完全免费的。
这是我上面写的另一个线索:您使用的块背后的象限已被释放,并包含指向下一个自由区域的指针。如果您的内存free()
,库会尝试合并自由块,第二个是损坏的,导致了此错误。
想象您有以下情况:
- 您的内存管理器预先启动每个内存块,无论是免费的还是分配的。
- 自由块在开始时具有下一个免费块的地址 - 这是我提到的链接列表。
- 您的分配的块,其长度为
- 一个自由块,以其长度进行预先准备,并包含Null下一个自由块的地址,如果没有下一个免费块。
然后,如果您在内存块的末端编写,将触摸和篡改下一个块的长度和内容。
这不会影响任何事情 - 到目前为止。
但是,如果您在块上调用free()
,则此块将与自由块合并。
为了这样做,必须发生以下操作:
- 遍历链接列表以找到相邻的自由块 - 这可能已经导致此错误,因为第二张自由区的"下一个"指针是垃圾。
- 从其他块中计算较大的自由块的大小。如果其中一个包含垃圾,则将使用垃圾来计算新的,更大的自由块大小,混乱是完美的。