0

这是代码:

#include <stdio.h>

int *addition(int a, int b);

int result;
int *result_ptr;

int *addition(int a, int b)
{
    int c = a + b;
    int *d = &c;

    return d;
}

int main(void)
{
    result = *(addition(1,2));  
    result_ptr = addition(1,2);

    printf("result = %d\n", result); //outputline1
    printf("result_ptr = %d\n", *result_ptr); //outputline2

    return 0;
}

如果在编写当前代码时对其进行编译和处理,result_ptr 会给出奇怪的值。但是,如果您交换 2 条输出线,则不会。为什么这样做?

4

1 回答 1

2

您正在返回局部变量的地址c。这是未定义的行为。也就是说,您的程序是错误的,这意味着它没有义务表现出可预测或理智的行为。改变两者的位置printf会给你另一个错误的程序,它(再次)不需要与之前的错误程序正确或连贯地运行。

编辑(添加来自 C99 标准草案 N1256 的相关引用 - 强调我的)

6.5.3.2 地址和间接运算符

[...]

语义

一元 * 运算符表示间接。如果操作数指向一个函数,则结果是一个函数指示符;如果它指向一个对象,则结果是一个指定该对象的左值。如果操作数的类型为 ''pointer to type'',则结果的类型为 ''type''。如果已为指针分配了无效值,则一元 * 运算符的行为未定义。87)

(脚注#87)

因此,&*E等价于E(即使E是空指针)&(E1[E2])((E1)+(E2)). 如果 E 是函数指示符或作为一元运算符的有效操作数的左值,则始终是&函数*&E指示符或等于 的左值E。If*P是左值并且T是对象指针类型的名称,*(T)P是具有与指向的类型兼容的类型的左值T

一元运算符取消引用指针的无效值包括*空指针、与指向的对象类型不适当对齐的地址以及对象在其生命周期结束后的地址。

相关的句子是最后一个(强调我的):当函数返回的地址被取消引用c时,局部变量已经结束了它的生命周期。additionmain

于 2013-09-14T11:07:35.907 回答