【发布时间】:2013-07-28 16:26:01
【问题描述】:
我正在阅读 Richard Reese 的新书(2013 年 5 月)O'Reilly 的新书“理解和使用 C 指针”,我对其中的一些代码有疑问,第 87 页。
if (++length > maximumLength) {
char *newBuffer = realloc (buffer, maximumLength += sizeIncrement);
if (newBuffer == NULL) {
free (buffer);
return NULL;
}
currentPosition = newBuffer + (currentPosition - buffer);
buffer = newBuffer;
}
我希望变量的名称是不言自明的;如果需要上下文,我将进行编辑以提供整个代码块,而不仅仅是这段摘录。
我的问题是关于currentPosition = newBuffer + (currentPosition - buffer); 这一行。我对realloc()的理解是,当新分配成功后,原来分配的内存就被释放了。如果这是正确的,那么有问题的行是使用悬空指针,init?该表达式的 RHS 上的 buffer 和 currentPosition 都是指向已释放内存的指针。
我的直觉是重写它以避免使用length 来避免使用悬空指针,毕竟它已经存在了。我想将最后两行替换为:
buffer = newBuffer;
currentPosition = buffer + length;
但是,可能编写的代码可以工作,因为这两个指针仍然保存地址(尽管是垃圾),并且这两个地址之间的偏移量仍然可以作为重新分配 currentPosition 的一种方式来计算。所以我对此感到不安只是小气吗?
概括一下这个问题:一旦指针悬空,是否可以安全地将指针中包含的地址用于任何目的,例如计算偏移量?谢谢。
【问题讨论】:
-
在重新分配时,
length比缓冲区的大小(调整前的maximumLength)大一。如果我正确解释了含义,您应该使用currentPosition = buffer + length - 1。 -
实际上,我在发布问题之前检查了这一点。本书的代码将
length和currentPosition都初始化为零。length在第一个条件中递增,因此它总是超过最后添加元素的索引。currentPosition是要添加新元素的位置,并在添加后递增。这不是我开始编写代码的方式,而是按照给定的代码,buffer + length是正确的。 -
所以
currentPosition是预先组合的buffer + length?我站得更正了(对冗余有点困惑)。 -
呃。丑陋的代码。也许至少添加一个 else ?我的批评是针对 R. Reese,而不是 OP。
-
@Jim,是的,可悲的是,它完全代表了本书的其余部分。