在 Address Arithmetic 一章中,函数 afree
定义如下:
static char allocbuf[ALLOCSIZE]; // storage for alloc
static char *allocp = allocbuf; // next free position
void afree(char *p)
{
if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
allocp = p;
}
据我所知,if 语句的要点是测试 p
是否在缓冲区的范围内。
但是,如果 p
不在缓冲区的范围内,比较会导致未定义的行为,不是吗?在进行比较之前,不需要将两个指针(p
和 allocbuf
)都转换为整数吗?
这个函数不应该是这个样子还是这个版本是错误的?
void afree(char *p)
{
uintptr_t p_int = (uintptr_t) p;
uintptr_t a_start = (uintptr_t) allocbuf;
uintptr_t a_end = (uintptr_t) (allocbuf + ALLOCSIZE);
if (p_int >= a_start && p_int < a_end)
allocp = p;
}
最佳答案
However, if p is not within the bounds of the buffer, the comparison results in undefined behavior, doesn't it?
是的。
Isn't it necessary to convert both pointers (
p
andallocbuf
) to integers before doing the comparison?
是的,这是通常的解决方法。
即便如此,>
的算术关系, <
还有一些==
没有为此类转换后的指针指定。您更新后的代码仍然不能按预期工作,但结果至少不是 UB。
考虑两个指针 int_street:1
和 char_street:4
可以指向相同的物理地址并比较等于指针,但作为整数 0x00010004, 0x00020004
是不同的。
请注意,K & R 是很久以前写的,甚至早于 Long Time Ago in a Galaxy Far Far Away什么时候(u)intptr_t
未定义。
C99 开始(u)intptr_t
.它们仍然是可选类型,尽管它们的实现非常普遍。
关于K&R 中 'afree' 函数的正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55840791/