通过取消引用 NULL 指针来分配引用

Posted

技术标签:

【中文标题】通过取消引用 NULL 指针来分配引用【英文标题】:Assigning a reference by dereferencing a NULL pointer 【发布时间】:2011-10-06 15:54:32 【问题描述】:
int&  fun()

    int * temp = NULL;
    return *temp;

在上述方法中,我正在尝试解除对 NULL 指针的引用。当我调用此函数时,它不会给出异常。我发现当返回类型是按引用时,如果它是按值,那么它不会给出异常。即使将 NULL 指针的取消引用分配给引用(如下行),它也不会给出。

int* temp = NULL:
int& temp1 = *temp;

这里我的问题是编译器在引用的情况下不做取消引用吗?

【问题讨论】:

引用在内部作为指针处理,它们只是在您对它们使用的语法上有所不同。知道您的取消引用仅将指针值“分配”给引用,使其成为对 NULL 的引用。这不会触发任何内存访问。当您按值返回时,取消引用将导致内存访问为 0,这几乎总是会给您一个段错误。 【参考方案1】:

取消引用空指针是未定义的行为

未定义的行为意味着任何事情都可能发生,因此无法为此定义行为。

诚然,我将第 n 次添加此 C++ 标准引用,但似乎有必要。

关于未定义的行为,

C++ 标准第 1.3.24 节规定:

允许的未定义行为范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行期间以环境特征的记录方式表现(无论是否发出诊断消息),到终止翻译或执行(发出诊断消息)。

注意: 此外,请注意:使用返回的引用或指向函数内部局部变量的指针也是未定义行为。您应该使用 new 在 freestore(heap) 上分配指针,然后返回指向它的引用/指针。

编辑:正如 @James McNellis 在 cmets 中适当指出的那样, 如果不使用返回的指针或引用,则行为定义明确

【讨论】:

是的,同意上述 UB。但我的问题是,如果取消引用 NULL 指针或非 NULL 指针以将其分配给引用,那么编译器是否执行取消引用操作?像- Int * t = NULL; int&t1 = *t; @G Mann:引用只是一个 alias 对它被初始化的原始类型。如何实现是编译器的实现细节,标准并没有定义它应该如何实现。 当你引用一个空指针时,代码是无效的,编译器可以做任何事情。问为什么它做了什么是没有意义的。 @G Mann - 究竟会发生什么取决于引用的实现方式。标准也没有说,只是参考应该如何工作。 “在函数内部返回对局部变量的引用或指针也是一种未定义的行为。”这是不正确的:如果返回的指针或引用没有被使用,那么行为是定义良好的。【参考方案2】:

当你取消引用一个空指针时,你不一定会得到一个异常;唯一可以保证的是行为是未定义的(这实际上意味着根本无法保证行为是什么)。

一旦对*temp 表达式求值,就无法推断程序的行为。

【讨论】:

我正在添加与我在其他帖子中所做的相同的评论 - 是的,同意上述 UB。但我的问题是,如果取消引用 NULL 指针或非 NULL 指针以将其分配给引用,那么编译器是否执行取消引用操作?像- Int * t = NULL; int&t1 = *t; 对于大多数编译器来说,在许多情况下,引用都是作为指针实现的。除此之外,还取决于编译器、设置等。 纠正我我错了。如果它被实现为指针,那么编译器可能不会执行取消引用操作。【参考方案3】:

不允许取消对空指针的引用,因此编译器可以在假设您不这样做的情况下生成代码。如果你仍然这样做,编译器可能会很好地告诉你,但它不是必须的。合同中规定你不能这样做。

在这种情况下,我打赌编译器很好地告诉你问题已经在编译时告诉你,如果你正确地设置警告级别。

【讨论】:

【参考方案4】:

不要 * 一个空指针,它是 UB。 (未定义的行为,你永远不能假设它会做任何事情,除了点燃你的狗并强迫你吃蘑菇,这会导致神话般的轶事)

Algol/C家族中空指针的一些历史和资料:http://en.wikipedia.org/wiki/Pointer_(computing)#Null_pointer

未定义行为的示例和含义:http://en.wikipedia.org/wiki/Undefined_behavior#Examples_in_C

【讨论】:

【参考方案5】:

我不确定我是否理解您要执行的操作。未定义 ** NULL** 指针的取消引用。

如果你想表明你的方法并不总是返回值,你可以将它声明为:

bool fun(int &val);

或stl方式(类似于std::map插入):

std::pair<int, bool> fun();

或提升方式:

boost::optional<int> fun();

【讨论】:

以上是关于通过取消引用 NULL 指针来分配引用的主要内容,如果未能解决你的问题,请参考以下文章

C++ 指针取消引用赋值

ctypes 不允许多次取消引用指针

通过取消引用更改 NSArray 中的值?

当我们在 C 中取消引用 NULL 指针时,操作系统会发生啥?

C语言visual studio警告:取消对NULL指针“p”的引用

取消引用指向访问元素的向量指针