在我正在编写的程序中,我正在实现二叉树和链表结构;因为我不知道我需要多少节点,所以我将它们放在堆上并让程序使用realloc(),如果它们需要更多空间的话。
问题是这样的结构包括指向同一结构中其他位置的指针,并且因为realloc()移动结构,我需要重做所有这些指针(除非我将它们更改为偏移,但这会增加复杂性代码和使用结构的成本,这比重新分配更常见。
现在,这可能不是问题;我可以使用旧指针,从新指针中减去它,并将结果添加到我需要更改的每个指针中。但是,这只有在可以减去两个指针并获得它们的地址差异(然后将该差异添加到另一个指针以获得前面多个字节的指针)时才有效;因为我正在堆上工作,我无法保证地址的差异可以被条目的大小整除,所以正常的指针减法(它给出了两者之间的对象数量)会引入错误。那么如何让它给我带来字节差异,即使它们位于堆的两个不同部分也能工作?
答案 0 :(得分:3)
要获得两个指针(以字节为单位)之间的差异,请将它们转换为char *
:
(char *) ptrA - (char *) ptrB;
但是,如果您希望实现二进制树或链接列表,并且所有节点共享同一块内存,请考虑使用结构数组,而指针将替换为数组索引。使用指针链接列表或树而不是结构数组的主要优点是,您可以单独添加或删除节点而无需重新分配内存或移动其他节点,但通过使节点共享相同的数组,您可以否定这一优势。
答案 1 :(得分:2)
对于您拥有的每个节点,最好的方法是malloc()
一个新块。但是这可能会对内存的内部管理产生一些开销,所以如果你有很多内存,那么确实一次为更多节点分配空间可能会很有用。
如果你需要重新分配,你应该采取另一种方式:
1. Calculate the offset within your memory block: `ofs = ptrX - start`
2. Add this offset to the new address returned by `realloc()`.
这样,你总是留在你分配的区域内,没有奇怪的堆指针差异,几乎没有意义。
答案 2 :(得分:0)
实际上,您可以使用malloc
或calloc
为每个节点获取内存。
所以你只需要记住树根节点的地址。
通过这种方式,您永远不需要realloc
整个树的记忆。每个节点的地址也永远不会改变。 :)