这是围绕Example of error caused by UB of incrementing a NULL pointer
的讨论的相关问题假设我定义了这个数据结构:
union UPtrMem
{
void* p;
char ach[sizeof(void*)];
}
UPtrMem u;
u.p = nullptr;
u.p++; // UB according to standards
u.ach[0]++; // why is this OK then??
p
和ach
共享相同的内存,因此仅仅是修改内存位置(恰好包含指针)UB的行为?一旦你试图取消引用指针,我认为它只会被取消定义。
答案 0 :(得分:10)
答案 1 :(得分:1)
标准使null
指针未定义递增的原因是因为并不总是null
指针包含像{{1}这样具有算术意义的值。 }}。它可以包含一个特定的位模式,指示0
的不可寻址内存。
你的例子也有其他问题。
当你增加一个已分配的指针时,它会将它指向的东西的大小添加到它的值。
因此,在CPU
计算机上32bit
可能会在向int*
添加4
时提前sizeof(int)
个位置。
1
的问题是编译器没有大小信息,因此无法知道增加其值的距离。
在你的示例中,您可以执行以下操作:
void*
根本不会增加指针,它会增加char数组的第一个元素中包含的u.ach[0]++;
值。当然,这是未定义的,即使它有效,也不能依赖它具有任何特定价值。
答案 2 :(得分:1)
你的例子不包含任何UB,因为你没有那么远:它是无法编译的无效代码。
要想拥有你正在考虑的那种UB,标题是“操纵nullptr时的UB”,你需要让代码执行。
当它不编译时就不会发生。
以防万一我的答案后问题发生了变化,这种情况对于这些明显设计到陷阱的响应者问题并不少见,这就是我写这篇文章所呈现的代码:
union UPtrMem
{
void* p;
char ach[sizeof(void*)];
}
UPtrMem u;
u.p = nullptr;
u.p++; // UB according to standards
u.ach[0]++; // why is this OK then??
增加void*
只是无效,不是受支持的操作,也不会编译。
答案 3 :(得分:-3)
似乎我u.p++;
甚至没有效果,因为void没有大小,所以没有任何增加。但是u.ach[0]++;
是有效的,因为你增加了一个字符。
编辑是的,它占用了结构中的空间......但是它指向的内容没有大小...它会增加什么?