-20
#include<iostream.h>
#include<conio.h>
#include<stdlib.h> 

int * add(int *, int *);
int add(int, int);

void main() {
    int a, b, sum, *z;
    cout << "enter the value of a & b";
    cin >> a >> b;
    z = add(&a, &b);
    sum = add(a, b);
    cout << "\nthe sum is: " << sum << endl;
    cout << "the sum is :" << *z << endl;   getch();
}

//.....calling with value..... 
int add(int a, int b) {
    int s;
    s = a + b;
    return s;
}

//......calling with address....... 
int *add(int *a, int*b) {
    int r;
    r = *a + *b;
    return &r;
}

为什么它给出错误的答案:

输出........ a=70 b=80 与值的总和是:150 与地址的总和是:1208

...但是当我将程序设置为:

#include<iostream.h>
#include<conio.h>
#include<stdlib.h> 

int * add(int *, int *);
int add(int, int);

void main() {
    int a, b, sum, *z;
    cout << "enter the value of a & b";
    cin >> a >> b;
    sum = add(a, b);
    cout << "\nthe sum is: " << sum << endl;
    z = add(&a, &b);
    cout << "the sum is :" << *z << endl;
    getch();
}

//.....calling with value..... 
int add(int a, int b) {
    int s;
    s = a + b;
    return s;
}

//......calling with address.......     
int *add(int *a, int*b) {
    int r;
    r = *a + *b;
    return &r;
}

它给出了正确的答案。

输出..... a=70 b=80 与值的总和是:150 与地址的总和是:150。

为什么?

4

2 回答 2

5
int *add(int *a,int *b) 
{   
   int r;      // r resides on stack
   r=*a+*b;
   return &r;

} // life time of r ends here.

您正在返回导致未定义行为的局部变量的地址。编译器应该警告过它。

于 2013-08-30T20:30:11.313 回答
3

当您返回r, in的地址时main,您将获得位于堆栈上的变量的地址,该地址位于当前“空闲”的堆栈区域中。释放后使用内存,无论是“陈旧的堆栈”还是“陈旧的堆”都是“未定义的行为”

在这种情况下,r将来对堆栈位置的任何使用都会r用其他一些“随机”值覆盖该值。在这种情况下,它看起来可能是函数的地址add(带int参数)。

我还建议您使用更现代的编译器(在大多数国家/地区还不足以合法申请驾驶执照的编译器)并启用警告。例如 GCC(它是免费软件,所以没有成本)——它会给出“局部变量的返回地址”的警告。

于 2013-08-30T20:34:31.167 回答