c++返回局部变量的指针 |
|
函数返回指针 。 原来便是一个 比较方便出问题的操作 。在霍顿的《VC++ 入门经典》一书中,给出了一个很有代表性的例子,如下: // Ex5_11.cpp #include <iostream> using std::cout; using std::endl; double* treble(double); // Function prototype int main(void) { double num = 5.0; // Test value double* ptr = 0; // Pointer to returned value ptr = treble(num); cout << endl << "Three times num = " << 3.0*num; cout << endl << "Result = " << *ptr; // Display 3*num cout << endl; system("pause"); return 0; } // Function to treble a value - mark 1 double* treble(double data) { double result = 0.0; result = 3.0*data; return &result; } 两个输出语句,一个直接输出3*5=15.另一个在一个函数中进行了乘法运算,也是5*3, 存到result变量中也没有任何问题 。返回这个变量的指针,输出时再接触 引用 。貌似也没有 舛误 。两条输出语句 仿佛都应该输出15.但事实不是这样 。编译 器会抛出[Warning] address of local variable `result' returned 这样一个 忠告信息 。程序运行后的 后果也并非是我们 料想的那样 。第二条输出语句会输出一个不可 预感的值 。这是怎么回事呢? 细心 综合一下,result是作用域在treble函数中的 部分变量 。当函数执行 完毕后 。变量result会被析构 。其原先占用的内存区域已经被系统回收, 可以存储任何数据 。而返回的指向该地址的指针也失去了其原有的 意思 。 因此我们得到这样一条准则: 永远不要从函数中返回 部分自动变量的地址 。 假如你真的需求这样操作 。你 可以在函数的参数表中传入一个指针变量 。 而后将需求写入的数据写入到该指针变量指向的地址 。由于该指针指向的变量,作用域在函数体 之外 。 因此不会在函数 完毕 完毕时被回收 。 现在回到我们遇到的问题 。 工夫函数localtime便是一个返回指针的函数 。返回值类 型:tm* 该如何 接纳这个返回值?固然是申明一个与之类型 雷同的变量 。 于是你会这样写:tm* result; 接下来呢?还用问?赋值嘛 。是否这样:result=localtime(....); 返回什么类型,固然要给什么类型的变量 赋值 。然而这样却 产生了我们不想看到的 后果 。 兴许你想到了 。便是这个指针!返回的指针在函数 完毕后不再有效 。正确的 步骤 可以是: tm result; result = *localtime(....); 也 可以是: tm* result; *result = *localtime(...); 正确的 步骤的一起特色是在函数 完毕前,对返回的指针解除 引用 。 而后用这个数值,为变量或指针指向的内存区域赋值 。也便是说必须要复制函 数的返回值 。由于函数体中变量会被析构 。 指针是灵便而 壮大的,幸免低级 舛误,明确 根本概念 。 威力让指针更好的为我们服务 。 |