Difference in behavior when returning a local reference or pointer
#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() {
开发者_StackOverflowB b;
b.show();
}
The problem in this is that I am returing a local varibale pointer/reference.
Currently it is char x[]="String"
, but when I use a pointer char *x="String"
, the result is "S"
but when Array reference the output comes as (i)
When you do something like:
char *f(){ return "static string"; }
You're returning the address of a string literal, but that string literal is not local to the function. Rather, it is statically allocated, so returning it gives well-defined results (i.e. the string continues to exist after the function exits, so it works).
When you (attempt to) return the address of an array of char like this:
char *f() {
char x[] = "automatically allocated space";
return x;
}
The compiler allocates space for x
on the stack, then initializes it from a string literal to which you don't have direct access. What you're returning is the address of the memory in the stack, not the string literal itself -- so as soon as the function exits, that array ceases to exist, and you have no idea what else might be put at that address. Trying to use that address causes undefined behavior, which means anything can happen.
That is because, when B::func()
the memory allocated for the x[]
is released hence if you try to access that memory location afterwards you will get garbage values. But when you do char *x="String"
, the memory for the string "String" is most probably allocated only once from the read-only section of your process memory. This address is guaranteed to remain valid until the execution of your program. In that case, if you try to access the pointer variable it will work correctly. BTW, as a side note, you need to declare a virtual base class destructor.
First off, figure out how to post code blocks. It's not hard, just indent them by four spaces.
Second, you should never return a pointer to a function-local variable. Because they're allocated on the stack, and all bets are off as regards to whether they're around after the function returns.
EDIT: This was written when the provided code was butchered and incomplete. My point doesn't apply to this particular case, but it's still important to know.
To try to be more precise: B::func() is returning a pointer to a hunk of memory that it used for a temporary array. There are absolutely no guarantees what is in that memory once the function returns. Either (1, simplest good practice ) the calling function can allocate memory and pass in a string buffer for the called function to use or (2) the called function needs to allocate a buffer and the calling function needs to later release it (but this requires a very disciplined approach by the developer of the calling function, and I'd never want to rely on that) or (3, probably really the best practice) the calling function can pass in some sort of smart pointer that will release its memory when it goes out of scope, and have the called function use that smart pointer to point to the memory it allocates.
精彩评论