返回本地引用或指针时的行为差异

时间:2009-12-14 05:38:48

标签: c++

#include <iostream.h>
using namespace std;

class A {
public:
   virtual char* func()=0;
};

class B :public A {
public:
   void show() {
      char * a;
      a = func();
      cout << "The First Character of string is " << *a;
   }
   char * func();
};


char* B::func() {
   cout << "In B" << endl;
   char x[] = "String";
   return x;
}

int main() {
   B b;
   b.show();
}

这个问题是我正在修复本地的varibale指针/引用。 目前它是char x[]="String",但是当我使用指针char *x="String"时,结果是"S"但是当数组引用时输出为(i)

4 个答案:

答案 0 :(得分:6)

当您执行以下操作时:

char *f(){ return "static string"; }

您将返回字符串文字的地址,但该字符串文字不是函数的本地。相反,它是静态分配的,因此返回它会给出明确定义的结果(即函数退出后字符串继续存在,因此它可以工作)。

当你(尝试)返回像这样的char数组的地址时:

char *f() { 
   char x[] = "automatically allocated space"; 
   return x; 
}

编译器在堆栈上为x分配空间,然后从您没有直接访问权限的字符串文字初始化它。你要返回的是堆栈中内存的地址,不是字符串文字本身 - 所以一旦函数退出,该数组就不再存在,你不知道还有什么可能会放在那个地址。尝试使用该地址会导致未定义的行为,这意味着任何事情都可能发生。

答案 1 :(得分:3)

这是因为,当B::func()x[]分配的内存被释放时,因此如果您之后尝试访问该内存位置,您将获得垃圾值。但是当你执行char *x="String"时,字符串“String”的内存很可能只从进程内存的只读部分分配一次。保证该地址在程序执行前保持有效。在这种情况下,如果您尝试访问指针变量,它将正常工作。 BTW,作为旁注,您需要声明一个虚拟基类析构函数。

答案 2 :(得分:0)

首先,弄清楚如何发布代码块。这并不难,只需用四个空格缩进它们。

其次,你永远不应该返回一个指向函数局部变量的指针。因为它们是在堆栈上分配的,并且所有的赌注都是关于它们是否在函数返回后都存在。

编辑:这是在提供的代码被屠杀和不完整时编写的。我的观点不适用于这种特殊情况,但知道这一点仍然很重要。

答案 3 :(得分:0)

为了更加精确:B :: func()返回一个指针,指向一个用于临时数组的内存块。一旦函数返回,绝对不能保证该内存中的内容。 (1,最简单的好习惯)调用函数可以分配内存并在字符串缓冲区中传递以供被调用函数使用或者(2)被调用函数需要分配缓冲区并且调用函数需要以后发布它(但这需要一个非常规范的方法,由调用函数的开发人员,我永远不想依赖它)或(3,可能真的是最好的做法)调用函数可以传递某种智能指针,当它超出范围时释放其内存,并让被调用的函数使用该智能指针指向它分配的内存。