(请参阅“编辑:更新的方案”)
这个问题可能是一个或另一个方面的重复,涉及到超出范围的对象指针的未定义行为的大量问题。但我在这里找到的所有问题主要是专门的用例。所以我想把这个问题颠倒过来,不要问是否禁止某些事情,但是究竟允许什么?
有一个可能的场景:你有一个带有指针的函数 - 你不知道它是否来自一个(仍然)有效的对象。哪些操作在所有情况下未定义的行为?哪个可能有未指明的副作用?
int * myFunc(const int * const A, int * B)
{
...
}
修改:更新了方案
在对问题的评论和Matt McNabbs answer中,有人指出UB最有可能上升,因为在调用场景中的函数期间使用了无效指针(s值)。因此,我将稍微改变一下场景(遵循Keith Thompsons answer中的示例):
int *ptr = malloc(sizeof *ptr);
/* the value of ptr is now valid, possibly NULL */
if (ptr != NULL)
{
/* the value of ptr is valid and non-null */
free(ptr);
/* the value of ptr is now invalid */
... /* here operations in question */
}
(由您的答案和评论填写并更正。)
sizeof(ptr)
void *
)。例如。 sizeof(*ptr)
(请参阅EOF和Jonathan Leffler 的评论)。ptr = NULL;
定义明确:访问指针的表示形式(例如来自Keith Thompson的answer):
unsigned char rep[sizeof ptr];
memcpy(rep, &ptr, sizeof ptr); /* ok, accesses the representation */
/* but not the value */
(由您的答案和评论填写并更正。)
这些操作通常被视为在无效指针上定义良好,但根据标准没有明确定义:
与所有未定义的行为一样,你可以使用许多机器上的指针来逃避(ab),但C标准并不保证你会逃脱并且有(或曾经是)机器滥用指针会导致程序失败。
一般来说,请参阅Keith Thompson's answer - 以及下面的广泛评论。
答案 0 :(得分:5)
任何使用无效指针值的行为都有未定义的行为。
int *ptr = malloc(sizeof *ptr);
// the value of ptr is now valid, possibly NULL
if (ptr != NULL) {
// the value of ptr is valid and non-null
free(ptr);
// the value of ptr is now invalid
ptr; // UNDEFINED BEHAVIOR
}
引文:N1570 6.2.4p2:
当指针变为不确定时,指针的值变得不确定 它指向(或刚刚过去)的对象到达其生命周期的末尾。
编译器可能不会为表达式语句ptr;
生成任何代码;当然,这是在未定义行为的范围内。
指针 object 上没有检索其值的任何操作(至少可能)定义良好:
sizeof ptr; // ok, doesn't use the value
sizeof *ptr; // ok, doesn't use the value, only the type
ptr = NULL; // ok
您还可以访问指针对象的表示,而无需访问其值:
unsigned char rep[sizeof ptr];
memcpy(rep, &ptr, sizeof ptr); // ok, accesses the representation
// but not the value
虽然你对结果的了解不多。
答案 1 :(得分:1)
这个问题非常广泛。但要回答您的具体情况:
int * myFunc(const int * const A, int * B)
如果使用无效指针值调用此函数,则它已经导致未定义的行为,方法是在准备调用函数时评估无效指针值。
您的所有要点"定义明确"没有明确的定义,因为一旦发生UB,猫就不能放回袋子里。