我正在尝试模拟空指针未定义的行为。 在下面的代码中应该进行哪些更改以引入空指针未定义的行为。
void foo( int * d )
{
printf("hello\n");
}
int main(void)
{
int a = 7 ;
int *b = malloc(sizeof(int)) ;
foo(b) ;
}
答案 0 :(得分:3)
在C 中取消引用NULL
指针(或当前address space之外的某个地址,通常在virtual memory中) < em>不 exception,但某些undefined behavior (通常为segmentation fault)。你really应该避免使用UB。
通过定义未定义的行为,我们无法解释它,而无需深入到非常具体的实现细节(编译器,运行时,优化,ASLR,机器代码,月亮阶段......)。
malloc
库函数可以(并且确实)失败。你应该总是测试它,至少如下:
int *b = malloc(sizeof(int));
if (!b) { perror("malloc of int"); exit(EXIT_FAILURE); };
要触发malloc
失败(但通常前几次调用malloc
仍然会成功),您可能会降低程序的可用地址空间。在Linux上,在父shell中使用ulimit
,或者调用setrlimit(2)。
malloc
,这总是失败:
// a silly, standard conforming, malloc which always fail:
void* malloc(size_t sz) {
if (sz == 0) return NULL;
errno = ENOMEM;
return NULL;
}
C 编程语言没有例外。 C ++(和Ocaml,Java,....)做(使用catch
&amp; throw
语句)。引发异常是控制流的非局部变化。在标准C中,您可以使用longjmp
来实现此目的。在C ++中,取消引用nullptr
是UB(并且不会引发C ++中不存在的任何空指针异常)。
答案 1 :(得分:2)
根据您的代码,我们可以像这样模拟Null Pointer UB,
#include<stdio.h>
void foo( int * d )
{
printf("hello, it is %d\n", *d);//dereference d (produces "Segmentation fault" if d is NULL)
}
int main(void)
{
int a = 7 ;
int *b = NULL; // simulate failed to malloc(sizeof(int))
foo(&a); // output is "hello, it is 7"
foo(b); // will trigger something like "Segmentation fault"
}
正如@Basile Starynkevitch指出的那样,在C 中没有例外,所以在这里更准确地说&#34; NULL指针UB(未定义行为)&#34;比较&#34; NULL指针异常&#34;。