交换输出线使程序错误(指针)

时间:2013-09-14 11:04:02

标签: c pointers

以下是代码:

#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个输出线,则不会。为什么这样做?

1 个答案:

答案 0 :(得分:2)

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

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

  

6.5.3.2地址和间接运算符

     

[...]

     

<强>语义

     

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

(脚注#87)

  

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

     

由一元*运算符取消引用指针的无效值中有一个空指针,一个地址与指向的对象类型不一致, 和后面的对象地址它的生命周期结束。

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