K&R 中 'afree' 函数的正确性

标签 c pointers

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 不在缓冲区的范围内,比较会导致未定义的行为,不是吗?在进行比较之前,不需要将两个指针(pallocbuf)都转换为整数吗?

这个函数不应该是这个样子还是这个版本是错误的?

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 and allocbuf) to integers before doing the comparison?

是的,这是通常的解决方法。

即便如此,>的算术关系, <还有一些==没有为此类转换后的指针指定。您更新后的代码仍然不能按预期工作,但结果至少不是 UB。

考虑两个指针 int_street:1char_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/

相关文章:

c - 给定一个字符串,将其子字符串存储在二维数组中

c - 为什么我收到错误 "Break statement not within loop or or switch."?

c - 函数返回类型和指针

c - qsort() - 比较函数参数

c++ - 这段代码中的 begin() 指针是如何创建的?

java - 如何从 JAVA 字符串(文件路径)发送到 C?

c - 编译器将哪种数据结构用于 C 中的变量参数列表?

sql - 在sql语句中使用变量-c接口(interface)

C++ 错误消息 : invalid pointer

c++ - 如何从 void 指针访问结构中的属性?