什么是空指针,什么是空指针?

Posted

技术标签:

【中文标题】什么是空指针,什么是空指针?【英文标题】:What is a void pointer and what is a null pointer? 【发布时间】:2011-05-19 02:27:26 【问题描述】:

所以我在处理一些面试问题时遇到了one about void and null pointers,它声称:

没有返回类型的指针称为空指针。它可以是任何类型的数据类型。

这让我彻底困惑了!根据这个问题,似乎 void 和 null 可以互换使用,我不认为这是正确的。我假设 void 是一个返回类型,而 null 是一个值。但我只是一个代码新手,我不确定我是对的。

请就什么是空指针和空指针表达您的看法。我不是在寻找无效和无效之间的区别。

【问题讨论】:

这是一个糟糕问题的糟糕答案,与 CSS 无关。忽略它并继续前进。 Lol 实际上 CSS 是一家公司:P 这家公司对我见过的愚蠢的面试官问题给出了最糟糕的答案。 【参考方案1】:

这两个概念是正交的:

    void 指针 (void *) 是指向某个内存位置的原始指针。 根据定义,空指针是不指向任何东西的特殊指针。它可以是指向任何类型、void 或其他类型的指针。

void 指针可以为空,也可以不为空:

void *void_ptr1 = nullptr;
void *void_ptr2 = malloc(42);
void *void_ptr3 = new Foo;               // void * can point to almost anything
void *void_ptr4 = (char*)void_ptr3 + 1;  // even somewhere inside an object

非空指针也可以为空:

Foo *f = nullptr;
Foo *g = new Foo;

【讨论】:

你能举个例子吗?你是说指向一个 void 函数之类的指针吗?我是新手,所以如果你能详细说明一下,我会更好:) void * 类型仅表示“指向内存的指针;我不知道那里有什么样的数据”。任何“正常”指针(int *char *MyStruct *)都可以隐式转换为void *;这是典型的“只是一点记忆”。 @Chowlett:是的,我的描述有点粗心。已修改。【参考方案2】:

void *ptr 是可用于指向任何类型数据的指针。可能是intfloatdouble。它没有返回类型,最初是使用指针类型(具有十六进制值)创建的指针,我们可以将此指针分配给任何类型的数据。

虽然空指针是地址为NULL值的指针,但该指针被赋予NULL值,因此它不能用于访问其地址在创建时可能包含的其他数据。我认为如果当前不使用指针 NULL,则将其分配为很好的编程技术。

【讨论】:

【参考方案3】:

空指针指向0x000000(访问指针不正确),而空指针是指向未指定类型的正确指针(void *)。但是void指针可以是空指针,但是不引用指针会产生错误。

【讨论】:

“不正确”是一个相当模糊的指针形容词。 NULL 是任何指针的有效值,但指针值为 NULL 时没有对象。此外,根据您的逻辑,void* 指针不能为 NULL,因为它既“正确”又“不正确”。这显然是不真实的。【参考方案4】:

void 类型一般意味着没有给出类型信息。

您应始终牢记,指针传达两条信息:所指数据的类型intdouble、...),它指定如何解释它,以及它所指向的数据的地址,它指定了在哪里你可以得到所指向的数据的实际值。

类型信息在指针的类型中(double*, int*, ...),而地址的数据是指针变量中包含的实际值。

因此,void 指针 (void *) 是一个不指定任何类型信息的指针。它会告诉您数据在哪里,但不会告诉您如何解释它。你知道那个地址有东西,但你不知道它是intdouble 还是一群飞牛。要实际使用此类数据,您必须以其他方式(例如使用其他魔术参数)获取有关它的类型信息,将该指针转换为常规指针类型,然后照常使用它。

void * 在 C 中经常用于为泛型编程提供某种支持;例如,参见qsort C 库函数。

相反,NULL 指针是一个不指向任何内容的指针。在这种情况下,通常存在有关指针的类型信息,但缺少的是指向数据的地址。当然,void * 也可以是 NULL

快速示例(假设v 被声明为double v;):

                         Type information present
             +----------------------+----------------------+
             |          ✔           |          ✘           |
         +---+----------------------+----------------------+
    p  c |   |                      |                      |
 v  o  o | ✔ | double * ptr = &v;   | void * ptr = &v;     |
 a  i  n |   |                      |                      |
 l  n  t +---+----------------------+----------------------+
 i  t  e |   |                      |                      |
 d  e  n | ✘ | double * ptr = NULL; | void * ptr = NULL;   |
    d  t |   |                      |                      |
         +---+----------------------+----------------------+

琐事NULL,至少在目前的标准中,保证为0。

在语言的其他领域,void 总是用于指定缺少类型。使用它作为返回值(注意:我现在谈论的是void,而不是void *)意味着该函数不返回任何值,并且将表达式转换为 void 是一种丢弃值的好方法(你'重新向编译器和其他程序员发出信号,表明你意识到你没有使用某个值)。

【讨论】:

【参考方案5】:

以下是指针算法的一些区别:

这源于 void 是一个不完整的类型。

void *vp;
vp++;     // error, incomplete type
vp += 2;  // same error

void *p = 0;
p++;      // still same error

int *p = 0;
p++;      // well-formed program, but UB ($5.6/5)

【讨论】:

所以基本上一个 void 指针不好,但它是一段有效的代码,是吗? @Shouvik:不不。有时它非常好,例如,当您只想将它​​作为不透明的句柄或其他东西传递而不透露它指向的实际类型时,或者例如如果您不希望被调用实体进行任何指针运算。所以这取决于 啊,好吧..就像闭包之类的东西? @Chubsdad:嗨,为什么你的最后一个例子是 int ptr UB?你能说吗?【参考方案6】:

请告诉我们:有什么区别:

在气罐和无气情况之间 在 cookie jar 和无 cookie 之间 介于“钱”和“空口袋”之间

如果你想出这些,你就可以掌握 null vs void* 的困境。

【讨论】:

我认为这种混淆是问题的真正原因......所以应该是所有相关知识编码的来源,因此我认为这将是一个合适的问题。抱歉,如果您有其他感觉... @Shouvik:你什么意思?这正是您问题的最佳答案!字面意思:) 嗯,我提到的原因是我不是一个经验丰富的程序员,现在我感兴趣的不仅仅是能够将一个程序放在一起,而是真正理解该语言及其更精细的方面。尽管两者之间缺乏比较,但我看到了笑话...... :) 大声笑,我明白了.. :D 如果你放 no-gas-tankno cookie jarno empty口袋我会更快地抓住它...... :)【参考方案7】:

void 是非类型。 null 是一个非值。

【讨论】:

是的,我已经在问题中表达了这种差异..寻找指针的差异.. void 一个类型,0或NULL 一个值 @armen: void 是一种表示缺少类型的类型。 null 也是一样。【参考方案8】:

链接的文章完全是错误的。它的第一句话:

没有返回类型的指针是 称为空指针

正在为我触发各种警报。这是一篇非常混乱的文章。

你几乎是正确的。 “指向 void 的指针”是一种类型(不是“返回类型”)。任何类型的值都可以由函数返回,因此是(函数的)返回类型。

空指针是一个指针,无论其类型如何,都指向空对象,该对象不是任何可以创建的有效对象。可以说空指针指向“无”。

指向 void 的指针也可以为空;

void *nothing = 0;

是完全有效的代码,只是说这个指针能够指向一个无类型的对象,但现在不是。

【讨论】:

感谢您的肯定。 bTW 空指针有什么特殊用途吗? @Shouvik 函数可以接受 void* 参数。如果你熟悉 Java 或 C#,大致相当于接受Object【参考方案9】:

完全忘记那个答案。引用您的链接:

"一个没有返回类型的指针是 称为空指针。”

这太简单了错误。指针的返回类型?真的吗?这是一个糟糕的来源......

void* 是通用指针type,因为任何指针类型(指向 const 和/或 volatile 的指针除外)都可以隐式转换为 void*。换句话说,您可以将任何指针分配给void* 类型的变量。空指针是指针 0

【讨论】:

谢谢我猜了这么多...现在坚持只是为了问题... :) 实际上,空指针的值可能不是'0',即使我从未见过它的任何其他值。在一些奇怪的平台上,0 可能是一个有效的指针值。 @Gianni 是的,你是对的,我很高兴这个信息能以你的评论形式与我的回答保持一致 这并不能解释 OP 正在寻找的差异 @Gianni:是的,知道。尽管空指针的底层表示(字节)取决于实现,但0 表示 C++ 语言中的空指针。当 0 被视为指针并根据实现生成正确的底层表示时,由编译器生成适当的代码。

以上是关于什么是空指针,什么是空指针?的主要内容,如果未能解决你的问题,请参考以下文章

有关C语言指针的问题:为啥最后结果是空指针?

Objective-C09-空指针和野指针

(int *)0 是空指针吗?

空指针是啥意思

空指针的大小

简析CWE-476:NULL Pointer Dereference空指针解引用漏洞