C99:数组或堆分配的缓冲区是否会以uintpttr_MAX结尾?
我可以假设下列不变量吗C99:数组或堆分配的缓冲区是否会以uintpttr_MAX结尾?,c,pointers,c99,intptr,C,Pointers,C99,Intptr,我可以假设下列不变量吗 void foo(char *buf, size_t len) { // "buf" points to either an array or memory allocated with malloc(). assert((uintptr_t)(buf + len) < UINTPTR_MAX); } 但是,如果malloc()返回内存,使得ptr+len==uintpttr_MAX,或者一个数组具有相同的属性,那么这个方案就会受阻。假设这永远不会发生,安
void foo(char *buf, size_t len) {
// "buf" points to either an array or memory allocated with malloc().
assert((uintptr_t)(buf + len) < UINTPTR_MAX);
}
但是,如果malloc()返回内存,使得
ptr+len==uintpttr_MAX
,或者一个数组具有相同的属性,那么这个方案就会受阻。假设这永远不会发生,安全吗?按照标准安全吗?如果不是,在实践中是否安全?C标准提供的唯一保证如下:
ISO/IEC 9899:1999(E)§7.18.1.4/1
以下类型使用属性指定有符号整数类型
任何指向void的有效指针都可以转换为此类型,然后
转换回指向void的指针,结果将比较为相等
指向原始指针:
intptr_t
uintptr_t
以下类型指定了一个
具有任何有效指针指向void的属性的无符号整数类型
可以转换为此类型,然后转换回指向void的指针,
结果将与原始指针进行比较:
intptr_t
uintptr_t
这些类型是可选的
无法保证这些转换整数的精确内容。特别是,给定一个字符指针p
,(uintptr\u t)(p+1)=((uintptpr\u t)p)+1
如果要标记偏移量,应使用另一个指针的ptrdiff\u t
偏移量,或者只需使用指针标记端点即可。例如:
void parse(char *buf, size_t len, char *end_of_submessage)
{
// ...
if (buf >= end_of_submessage)
process_submsg_end();
}
如果_子消息的end_
可能位于不同的缓冲区中,则可以使用以下内容:
char *buf_start = buf;
// ...
if (buf_start <= end_of_submessage && buf >= end_of_submessage)
process_submsg_end();
char*buf\u start=buf;
// ...
if(buf_开始=_子消息的结束)
进程_submsg_end();
您的观点已被采纳,但不幸的是,您的解决方案对我不起作用,因为我试图标记的end\u子消息可能不在当前缓冲区中(考虑为单个逻辑流读取多个物理缓冲区的情况)。使用您描述的方案,无论子消息是否在当前缓冲区中结束,当到达此缓冲区的末尾时,我们都将运行process_submsg_end()。还要注意,UINT_MAX附近的地址是。@Josh Haberman:您可以使用NULL
作为“end is in other buffer”值,然后使用if(end_of_submessage&&buf>=end_of_submessage)
作为测试。