[RESOLVED] "returning address of local variable or temporary"

Started by
17 comments, last by SiCrane 18 years, 7 months ago
I am getting the warning "warning C4172: returning address of local variable or temporary" in a few of my functions that returns a char*. Here is the code in a function that I get the error. It returns the selected item in the listbox.

	char Text[256];
	SendMessage(m_hWnd, LB_GETTEXT, (WPARAM)SelectedIndex(), (LPARAM)&Text);
	return Text;


I know lots of people don't like char's and put so much emphasis on strings, but I would like to add functions to handle both strings and char's. I could change char Text[256] to char* Text = new char[256] and it works fine, but then I have a new pointer that I would need to delete every time I run the function. Is there a way to change the code I am using to fix this? I know I could change all the functions I use this type of code in and put an extra parameter to accept a variable to put the text into and not return anything, or I could probably create a new char and lstrcpy it into a char array and delete it, but it might cause the same error, I am not sure how to go about fixing it the best way. Thanks in advance. [Edited by - GetWindowRect on September 9, 2005 9:29:04 PM]
Advertisement
Quote:Original post by GetWindowRect
I am getting the warning "warning C4172: returning address of local variable or temporary" in a few of my functions that returns a char*.

Here is the code in a function that I get the error.
It returns the selected item in the listbox.
*** Source Snippet Removed ***

I know lots of people don't like char's and put so much emphasis on strings, but I would like to add functions to handle both strings and char's.

I could change char Text[256] to char* Text = new char[256] and it works fine, but then I have a new pointer that I would need to delete every time I run the function. Is there a way to change the code I am using to fix this?

I know I could change all the functions I use this type of code in and put an extra parameter to accept a variable to put the text into and not return anything, or I could probably create a new char and lstrcpy it into a char array and delete it, but it might cause the same error, I am not sure how to go about fixing it the best way. Thanks in advance.

The best way is to stop using cstrings and don't encourage their use by adding support for them to your library. Failing that, you can't return local references, it doesn't work. So there is no way around either returning a dynamic array, or accepting memory as a parameter. I prefer the later, since there is no question as to ownership. Of course, you then have to watch for buffer overruns more closely.

void newFunc(char* text, unsigned buffer_length){    strncpy(text, "message", buffer_length);    return text;}


CM
Quote:Original post by Conner McCloud
Quote:Original post by GetWindowRect
I am getting the warning "warning C4172: returning address of local variable or temporary" in a few of my functions that returns a char*.

Here is the code in a function that I get the error.
It returns the selected item in the listbox.
*** Source Snippet Removed ***

I know lots of people don't like char's and put so much emphasis on strings, but I would like to add functions to handle both strings and char's.

I could change char Text[256] to char* Text = new char[256] and it works fine, but then I have a new pointer that I would need to delete every time I run the function. Is there a way to change the code I am using to fix this?

I know I could change all the functions I use this type of code in and put an extra parameter to accept a variable to put the text into and not return anything, or I could probably create a new char and lstrcpy it into a char array and delete it, but it might cause the same error, I am not sure how to go about fixing it the best way. Thanks in advance.

The best way is to stop using cstrings and don't encourage their use by adding support for them to your library. Failing that, you can't return local references, it doesn't work. So there is no way around either returning a dynamic array, or accepting memory as a parameter. I prefer the later, since there is no question as to ownership. Of course, you then have to watch for buffer overruns more closely.

*** Source Snippet Removed ***

CM


You said "you can't return local references". I am a little confused as to how this works. I thought in order to return a "reference" I had to use the & sign in front of the variable. Although, it works fine and I have not ran into any problems using this method. Could you explain when or how this would cause an issue? I would look into the other method though, thank you for your help.

You can always use a c++ string and get a const char* through string::c_str() if you need it. It will prevent a lot of headaches in the future too probably... :)
Quote:Original post by GetWindowRect
Quote:Original post by Conner McCloud
Quote:Original post by GetWindowRect
I am getting the warning "warning C4172: returning address of local variable or temporary" in a few of my functions that returns a char*.

Here is the code in a function that I get the error.
It returns the selected item in the listbox.
*** Source Snippet Removed ***

I know lots of people don't like char's and put so much emphasis on strings, but I would like to add functions to handle both strings and char's.

I could change char Text[256] to char* Text = new char[256] and it works fine, but then I have a new pointer that I would need to delete every time I run the function. Is there a way to change the code I am using to fix this?

I know I could change all the functions I use this type of code in and put an extra parameter to accept a variable to put the text into and not return anything, or I could probably create a new char and lstrcpy it into a char array and delete it, but it might cause the same error, I am not sure how to go about fixing it the best way. Thanks in advance.

The best way is to stop using cstrings and don't encourage their use by adding support for them to your library. Failing that, you can't return local references, it doesn't work. So there is no way around either returning a dynamic array, or accepting memory as a parameter. I prefer the later, since there is no question as to ownership. Of course, you then have to watch for buffer overruns more closely.

*** Source Snippet Removed ***

CM


You said "you can't return local references". I am a little confused as to how this works. I thought in order to return a "reference" I had to use the & sign in front of the variable. Although, it works fine and I have not ran into any problems using this method. Could you explain when or how this would cause an issue? I would look into the other method though, thank you for your help.


A char* is a type of reference (a pointer).
Here's the deal with why what you're doing doesn't work:

When you declare

char Text[256];

in a function the compiler generates code to create memory on the stack everytime that function is called. When you exit the function (with return) any memory declared on the stack is destroyed, so returning a reference to it doesn't make sense -- it's not there. As has been mentioned, there is really no reason to add "support" for both cstrings and std::string to your app. Just use std::string (which will then use its copy constructor when ever you return one) and pull cstrings out of it whenever you need.

Mage
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
The reason it gives you this error is because a local variable only exists while the function it is local to exists. When the function ends, it (the variable) is deleted into the great void. By returning a reference to a local variable, the variable the reference is to will no longer exist, and the memory could contain anything.

I hope that makes sense.
Roboguy:
I know a char* is a type of reference, but I am not using that, I am using char [256] not char*.

Mage:
I am still learning c++. I know tons of people are extremely opinionated about strings being so much "better" than char's because they are easier and all that, but I am learning so I would like to understand both. Which is why I am adding code to work with both. Might not be smart, but I am learning and would like to learn alternatives, hence both char and string.

Thank you for the explanation, that makes a little more sense. The only way I use this is for one time purpose type things, hence never running into problems. I guess, other than the std::string class, there is no other way of accomplishing what I am trying to do unless I accept a return value as a parameter like CM mentioned.

Thanks again to all of you for your replies, I appreciate it.
Quote:Original post by GetWindowRect
You said "you can't return local references". I am a little confused as to how this works. I thought in order to return a "reference" I had to use the & sign in front of the variable. Although, it works fine and I have not ran into any problems using this method. Could you explain when or how this would cause an issue? I would look into the other method though, thank you for your help.

Apologies, I was using poor terminology. I meant a pointer to local memory. References do that as well, and they're just as bad an idea.

The basic problem is that the local variables are going to go out of scope, at which point their memory can be reused by something else. If you have a pointer to that memory, then its value is going to change on you at some point without warning. Probably at the next function call, but there's really no telling.

The reason you haven't noticed a problem is because you've gotten lucky. You've used your pointers/references before the stuff gets overwritten, so there are no issues. Much like why buffer overruns aren't noticed more quickly: the testers get lucky and don't write over anything vital.

The moral is if you have local memory, it isn't there any more after it goes out of scope. Hense the warning, which you really shouldn't ignore. Always return copies of items, or dynamic memory [which remains valid until you call delete].

CM
Quote:Original post by GetWindowRect
Roboguy:
I know a char* is a type of reference, but I am not using that, I am using char [256] not char*.


Arrays are pointers.

This topic is closed to new replies.

Advertisement