真空安全是否在C中实现?

真空安全是否在C中实现?,c,void,C,Void,根据, 无效安全是面向对象编程中的一个保证 语言表示没有对象引用具有空值或无效值 这是正确的,但是C不是一个面向对象的PL,并且该定义只适用于对空指针或对象实例引用的解除保护 那么,C中是否存在空洞安全性?这个术语(或其相反)是否可以用来描述语言?< P>不。但是如果使用指针,C++也没有(面向对象的编程语言之一)。C++引用是指总是引用真实对象的指针,指针在C和C++中都可以为空。你可以在C++中得到悬空引用,但是作为未定义的行为,你已经打破了规则,所有的赌注都被关闭了。 C本身没有引用,只有

根据,

无效安全是面向对象编程中的一个保证 语言表示没有对象引用具有空值或无效值

这是正确的,但是C不是一个面向对象的PL,并且该定义只适用于对空指针或对象实例引用的解除保护


那么,C中是否存在空洞安全性?这个术语(或其相反)是否可以用来描述语言?

< P>不。但是如果使用指针,C++也没有(面向对象的编程语言之一)。C++引用是指总是引用真实对象的指针,指针在C和C++中都可以为空。你可以在C++中得到悬空引用,但是作为未定义的行为,你已经打破了规则,所有的赌注都被关闭了。 C本身没有引用,只有指针,并且您根本无法获得该级别的保护,除非您自己手动执行:

if (ptr != NULL)
    doSomethingWith (*ptr);
在C语言中,代码类似于:

char *xyzzy = NULL;
char plugh = *xyzzy;

只是自找麻烦,但是编译器不会阻止你这么做,因为它是完全合法的(尽管C++案例中没有定义的行为).< /p> 不,但是如果你使用指针,C++也没有(面向对象的编程语言之一)。C++引用是指总是引用真实对象的指针,指针在C和C++中都可以为空。你可以在C++中得到悬空引用,但是作为未定义的行为,你已经打破了规则,所有的赌注都被关闭了。 C本身没有引用,只有指针,并且您根本无法获得该级别的保护,除非您自己手动执行:

if (ptr != NULL)
    doSomethingWith (*ptr);
在C语言中,代码类似于:

char *xyzzy = NULL;
char plugh = *xyzzy;

只是自找麻烦,但是编译器不会阻止你这么做,因为它是完全合法的(尽管C++的情况下,未定义的行为)。

< P> C.没有空安全性,C中没有引用,只是指针。指针可以设置为NULL,取消NULL ptr会导致分段错误,如示例所示:

int main(int argc, char **argv) {
    int val = 5555;
    int val2 = 555;


    int *ptr;

    ptr = &val; /* ptr now points to the address of val */

    printf("Address: 0x%.8x [0x%.8x]", &ptr, &val);

    printf("\nAddress: 0x%.8x [0x%.8x]", ptr, &val);

    printf("\nValue: %d [%d]", *ptr, val);  



    ptr = &val2;

    printf("\n\n\nNew Address: 0x%.8x [0x%.8x]", &ptr, &val2);

    printf("\nNew Address: 0x%.8x [0x%.8x]", ptr, &val2);

    printf("\nNew Value: %d [%d]\n\n", *ptr, val2);


    ptr = NULL;

    printf("\nptr = %d", ptr);

    printf("\n&ptr = 0x%.8x", &ptr);

    // printf("\n*ptr = %d", *ptr); /* causes segfault */

    return 0;
}
char@char:~$/a.out

地址:0xf8638e50[0xf8638e5c]

地址:0xf8638e5c[0xf8638e5c]

数值:5555[5555]

新地址:0xf8638e50[0xf8638e58]

新地址:0xf8638e58[0xf8638e58]

新值:555[555]

ptr=0

&ptr=0xf8638e50


但如果取消对printf的最后一个调用的注释,则会得到:


char@char:~$/a.out

地址:0xfbb6cae0[0xfbb6caec]

地址:0xfbb6caec[0xfbb6caec]

数值:5555[5555]

新地址:0xfbb6cae0[0xfbb6cae8]

新地址:0xfbb6cae8[0xfbb6cae8]

新值:555[555]

ptr=0


分段错误

C中没有空安全。C中没有引用,只有指针。指针可以设置为NULL,取消NULL ptr会导致分段错误,如示例所示:

int main(int argc, char **argv) {
    int val = 5555;
    int val2 = 555;


    int *ptr;

    ptr = &val; /* ptr now points to the address of val */

    printf("Address: 0x%.8x [0x%.8x]", &ptr, &val);

    printf("\nAddress: 0x%.8x [0x%.8x]", ptr, &val);

    printf("\nValue: %d [%d]", *ptr, val);  



    ptr = &val2;

    printf("\n\n\nNew Address: 0x%.8x [0x%.8x]", &ptr, &val2);

    printf("\nNew Address: 0x%.8x [0x%.8x]", ptr, &val2);

    printf("\nNew Value: %d [%d]\n\n", *ptr, val2);


    ptr = NULL;

    printf("\nptr = %d", ptr);

    printf("\n&ptr = 0x%.8x", &ptr);

    // printf("\n*ptr = %d", *ptr); /* causes segfault */

    return 0;
}
char@char:~$/a.out

地址:0xf8638e50[0xf8638e5c]

地址:0xf8638e5c[0xf8638e5c]

数值:5555[5555]

新地址:0xf8638e50[0xf8638e58]

新地址:0xf8638e58[0xf8638e58]

新值:555[555]

ptr=0

&ptr=0xf8638e50


但如果取消对printf的最后一个调用的注释,则会得到:


char@char:~$/a.out

地址:0xfbb6cae0[0xfbb6caec]

地址:0xfbb6caec[0xfbb6caec]

数值:5555[5555]

新地址:0xfbb6cae0[0xfbb6cae8]

新地址:0xfbb6cae8[0xfbb6cae8]

新值:555[555]

ptr=0


分段错误

当没有对象引用时(例如在C中),很容易保证没有对象引用具有null或void值


说C具有空安全性是正确的,但它也毫无意义。有关更多信息,请参见:

当没有对象引用时(例如在C中),很容易保证没有对象引用具有null或void值


说C具有空安全性是正确的,但它也毫无意义。有关详细信息,请参阅:

您是否曾设法在C中取消引用无效指针?否,基本上您需要检查指针是否为NULL或not,然后您可以执行该指针。@rabishaw然后您可以取消引用该指针。它不是空的,我们不能保证它指向某个合理的地方。@juanchopanza。。。空值检查是为了安全起见。。。如果指针不指向任何地方/或没有任何值,并且您尝试遵从它。。它会导致崩溃,对吗?@rabishaw您的第一条评论是,只要指针不为空,取消引用指针是安全的。我在补充一点说明。您是否曾设法在C中取消对无效指针的引用?不,基本上您需要检查指针是否为NULL或not,然后您可以执行该指针。@rabishaw,然后您可以取消对该指针的引用。它不是空的,我们不能保证它指向某个合理的地方。@juanchopanza。。。空值检查是为了安全起见。。。如果指针不指向任何地方/或没有任何值,并且您尝试遵从它。。它会导致崩溃,对吗?@rabishaw您的第一条评论是,只要指针不为空,取消引用指针是安全的。我在添加一个澄清。即使在C++中,我们也可以有悬空引用(尽管我们必须更努力地尝试)。@ 5Go12Ed:好的点,使我的陈述有点不那么有意义。@ 5Go12EDER,但是他们不会有“空或无效”的值。这意味着,为了不保证无效安全,语言有这样的概念,引用可以包含这些概念。它涵盖了我能想到的大多数编程语言。除非程序已经触发了未定义的行为(在该点不再被C++规则覆盖,包括与“空隙安全”相关的任何规则),甚至C++中,我们也不能在C++中有空/悬空引用。