在C语言中模拟空指针未定义的行为

在C语言中模拟空指针未定义的行为,c,pointers,C,Pointers,我试图模拟空指针未定义的行为。 应在下面的代码中进行哪些更改以引入空指针未定义行为 void foo( int * d ) { printf("hello\n"); } int main(void) { int a = 7 ; int *b = malloc(sizeof(int)) ; foo(b) ; } 以下是如何取消对空指针的引用: int *b = 0; *b = 3; 以下是如何取消对空指针的引用: int *b = 0; *b = 3;

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

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

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

以下是如何取消对空指针的引用:

 int *b = 0;
 *b = 3;

以下是如何取消对空指针的引用:

 int *b = 0;
 *b = 3;

根据你的代码,我们可以像这样模拟空指针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"
}
#包括
无效foo(int*d)
{
printf(“您好,它是%d\n”,*d);//取消引用d(如果d为NULL,则生成“分段错误”)
}
内部主(空)
{
INTA=7;
int*b=NULL;//模拟malloc失败(sizeof(int))
foo(&a);//输出为“您好,它是7”
foo(b);//将触发类似“分段错误”的内容
}

正如@Basile Starynkevitch所指出的,C中没有异常,因此在这里说“空指针UB(未定义的行为)”比“空指针异常”更准确。

根据您的代码,我们可以像这样模拟空指针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"
}
#包括
无效foo(int*d)
{
printf(“您好,它是%d\n”,*d);//取消引用d(如果d为NULL,则生成“分段错误”)
}
内部主(空)
{
INTA=7;
int*b=NULL;//模拟malloc失败(sizeof(int))
foo(&a);//输出为“您好,它是7”
foo(b);//将触发类似“分段错误”的内容
}

正如@Basile Starynkevitch所指出的,C中没有异常,因此在这里说“空指针UB(未定义的行为)”比“空指针异常”更准确。

在C中取消引用
NULL
指针(或当前地址之外的某个地址,通常在中)不是,但是有些人(通常是a)。你应该避免使用UB

根据未定义行为的定义,如果不深入到非常具体的实现细节(编译器、运行时、优化、机器代码、月球阶段等等),我们无法解释它

malloc
库函数可能(而且确实)失败。您应该始终测试它,至少是:

 int *b = malloc(sizeof(int));
 if (!b) { perror("malloc of int"); exit(EXIT_FAILURE); }; 
要触发
malloc
失败(但通常对
malloc
的前几个调用仍然会成功),您可以降低程序的可用地址空间。在Linux上,在父shell中使用
ulimit
,或调用

顺便说一句,你甚至可以链接到你自己的
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 < /COD>和<代码>抛出语句)。引发异常是控制流的非本地更改。在标准C中,您可以为此使用
longjmp
。在C++中,一个代码< > NulLPTR>代码>是UB(并且不增加任何C++中不存在的空指针异常)。<> >强> >取消代码<空> <代码>指针<强>(或者在当前之外的一些地址,通常在C <强>中< <强> >不是“A”,但<强> > < /强>(通常为A)。你应该避免使用UB

根据未定义行为的定义,如果不深入到非常具体的实现细节(编译器、运行时、优化、机器代码、月球阶段等等),我们无法解释它

malloc
库函数可能(而且确实)失败。您应该始终测试它,至少是:

 int *b = malloc(sizeof(int));
 if (!b) { perror("malloc of int"); exit(EXIT_FAILURE); }; 
要触发
malloc
失败(但通常对
malloc
的前几个调用仍然会成功),您可以降低程序的可用地址空间。在Linux上,在父shell中使用
ulimit
,或调用

顺便说一句,你甚至可以链接到你自己的
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 < /COD>和<代码>抛出语句)。引发异常是控制流的非本地更改。在标准C中,您可以为此使用
longjmp
。在C++中,一个代码< > NulLPTR< /C>是UB(并且没有增加C++中不存在的空指针异常)。< /P>它的可能的副本解释了空指针异常,但是我想知道如何在这里引入空指针异常。请删除重复的标记。C中没有异常,因此C中不可能有任何
NULL
指针异常。实际上,这个问题是错误的,没有意义,因为C中没有异常。您需要理解未定义行为的含义。嗨,Basile,感谢您指出它的未定义行为,而不是异常。我请求帮助模拟C中未定义的空指针解引用行为。Eric Tsui先生给出的答案正是我所要求的。可能的重复解释了空指针异常,但我想知道如何在这里引入空指针异常。请删除重复的标记。C中没有异常,因此C中不可能有任何
NULL
指针异常。实际上,这个问题是错误的,没有意义,因为C中没有异常。您需要理解未定义行为的含义。嗨,Basile,感谢您指出它的未定义行为,而不是异常。我请求帮助模拟C中未定义的空指针解引用行为。Eric Tsui先生给出的答案正是我所要求的。嗨,伙计,你能告诉我代码到底在做什么吗?不,用标准C透视图。这是一个未定义的行为。嗨,伙计,你能告诉我代码到底在做什么吗?不,用标准的C透视图。这是一种未定义的行为。错误。这里没有例外,只是一些未定义的behavior@BasileStarynkevitch同意。因为问题被标记为
c
tag,“c”毫无例外。所以我假设问题所有者对于“空指针异常”的含义是由空指针引起的一些“异常行为”,即UB。无论如何,你是对的。这是未定义的行为