在C中模拟Null Pointer未定义的行为

时间:2015-07-15 04:23:38

标签: c pointers

我正在尝试模拟空指针未定义的行为。 在下面的代码中应该进行哪些更改以引入空指针未定义的行为。

void foo( int * d )
{
    printf("hello\n");
}

int main(void)
{
    int a = 7 ;
    int *b = malloc(sizeof(int)) ;
    foo(b) ;
}

2 个答案:

答案 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;。