4

在我正在编写的程序中,我正在实现二叉树和链表结构;因为我不知道我需要多少节点,所以我将它们放在堆上,如果它们需要更多空间,我会让程序使用 realloc()。

问题是这样的结构包括指向同一结构中其他位置的指针,并且由于 realloc() 移动结构,我需要重做所有这些指针(除非我将它们更改为偏移量,但这会增加代码的复杂性和使用结构的成本,这比重新分配更常见)。

现在,这可能不是问题;我可以只取旧指针,从新指针中减去它,然后将结果添加到我需要更改的每个指针中。但是,这仅适用于可以减去两个指针并获得它们地址的差异(然后将该差异添加到另一个指针以获得指针前面那么多字节的指针);因为我在堆上工作,我不能保证地址的差异可以被条目的大小整除,所以正常的指针减法(它给出了中间的对象数)会引入错误。那么我如何让它给我字节的差异,即使它们在堆的两个不同部分中也能工作?

4

3 回答 3

3

要以字节为单位获取两个指针之间的差异,请将它们转换为char *

(char *) ptrA - (char *) ptrB;

但是,如果您想实现所有节点共享同一块内存的二叉树或链表,请考虑改用结构数组,并将指针替换为数组索引。将指针用于链表或树而不是结构数组的主要优点是,您可以单独添加或删除节点,而无需重新分配内存或移动其他节点,但是通过使节点共享相同的数组,您重新否定了这个优势。

于 2013-08-07T21:34:48.633 回答
2

最好的方法确实是为malloc()您拥有的每个节点创建一个新块。但这可能会对内存的内部管理产生一些开销,所以如果你有很多内存,那么一次为更多节点分配空间可能很有用。

如果你需要重新分配,你应该采取另一种方式:

1. Calculate the offset within your memory block: `ofs = ptrX - start`
2. Add this offset to the new address returned by `realloc()`.

这样,您始终停留在您分配的区域内,并且没有几乎没有意义的奇怪堆指针差异。

于 2013-08-07T22:01:27.980 回答
0

实际上,您可以使用mallocorcalloc来获取每个节点的内存。

所以你只需要记住树的根节点的地址。

通过这种方式,您永远不需要realloc为整棵树存储内存。每个节点的地址也永远不会改变。:)

于 2013-08-07T22:26:01.147 回答