K&R中“ afree”功能的正确性

时间:2019-04-25 01:58:55

标签: c pointers

在<地址>地址算术一章中,函数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;
}

1 个答案:

答案 0 :(得分:1)

  

但是,如果p不在缓冲区的范围内,则比较会导致未定义的行为,不是吗?

是的

  

在进行比较之前,是否不必将两个指针(pallocbuf)都转换为整数?

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

即使如此,也未为此类转换后的指针指定><和某些==的算术关系。您更新后的代码仍然无法按预期运行,但结果至少不是UB。

考虑两个指针int_street:1char_street:4可以指向相同的物理地址,并且比较起来与指针相等,但是整数0x00010004, 0x00020004不同。


请注意,K&R是在很早以前写的,甚至在(u)intptr_t未定义的时候,甚至在Long Time Ago in a Galaxy Far Far Away之前也写过。

C99已启动(u)intptr_t。它们仍然是可选类型,即使它们非常普遍地实现。