c-释放阵列在由MPI_RECV编写后



我有一个我用 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(),则此块将与自由块合并。

为了这样做,必须发生以下操作:

  • 遍历链接列表以找到相邻的自由块 - 这可能已经导致此错误,因为第二张自由区的"下一个"指针是垃圾。
  • 从其他块中计算较大的自由块的大小。如果其中一个包含垃圾,则将使用垃圾来计算新的,更大的自由块大小,混乱是完美的。

相关内容

  • 没有找到相关文章

最新更新