我在阅读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()
的理解是,当新的分配成功时,最初分配的内存将被释放。如果这是正确的,那么这一行代码使用了悬空指针,对吗?在该表达式中,右侧的buffer
和currentPosition
都是指向已被释放的内存的指针。
我的直觉是通过使用length
来重新编写代码以避免使用悬空指针。毕竟,length
已经存在。我想用以下代码替换这些最后两行:
buffer = newBuffer;
currentPosition = buffer + length;
然而,假设代码能够正常工作是因为这两个指针仍然保留了地址(虽然可能是垃圾值),并且这两个地址之间的偏移量可以被用来重新分配 currentPosition
。所以说,我对此感到不安是否只是过于挑剔?
一般化问题:一旦指针变成悬空状态,是否可以安全地将指针中包含的地址用于任何目的,例如计算偏移量?谢谢。
length
的值比缓冲区大小(调整前的maximumLength
)大 1。如果我理解正确的话,你应该使用currentPosition = buffer + length - 1
。 - Caseylength
和currentPosition
都初始化为零。length
在第一个条件语句中递增,因此它始终比最后添加的元素的索引多一。currentPosition
是新元素要添加的位置,在添加后会递增。这不是我一开始编写代码的方式,但是考虑到给定的代码,buffer + length
是正确的。 - verbosecurrentPosition
是一个预组合的buffer + length
?我纠正了(并且对冗余感到有些困惑)。 - Casey