Results 1 to 5 of 5
Hi,
I Inherited the following code:
Code:
string IntToString(int nVal)
{
char sVal[254];
memset(sVal, 0, 253);
sprintf(sVal, "%d", nVal);
string strVal = sVal;
return strVal;
}
I know that the ...
- 12-28-2010 #1Just Joined!
- Join Date
- Jul 2010
- Posts
- 5
C++ Local scope variable passed back. Issue?
Hi,
I Inherited the following code:
Code:string IntToString(int nVal) { char sVal[254]; memset(sVal, 0, 253); sprintf(sVal, "%d", nVal); string strVal = sVal; return strVal; }
I know that the scope for strVal ends after the return happens. I also know that strVal is left on the stack and, as far as I know, this code works.
According to the standards this code is violating scope rules.
Now the big question; in a single threaded LINUX application, is this a major issue or not?
- 12-28-2010 #2
What standards is this violating?
I'm not a C++ expert, but I believe that in this instance, the code should work okay.
The usual problem with returning local-scope variables is when you return pointers to variables that are deallocated at the end of the function:
This code will not work because the memory for buf is deallocated at the end of the function, but you are passing back a pointer. So the program will segfault once the pointer is accessed.Code:char *foo(void) { char buf[1024]; buf[0] = 'f'; buf[1] = 'o'; buf[2] = 'o'; buf[3] = '\n'; return buf; }
The correct way around this is to allocate the memory for the buffer on the heap:
In your instance, you are not returning a pointer, but a string object. Even though you have the buffer allocated on the stack like in the examples above, this line:Code:char *foo(void) { char *buf = malloc(1024); buf[0] = 'f'; buf[1] = 'o'; buf[2] = 'o'; buf[3] = '\n'; return buf; }
is functionally equivalent to:Code:string strVal = sVal;
which is to say, you are constructing a string object based on the buffer. So your code is not returning the array, but a string object that contains a copy of the array internally.Code:string strVal(sVal);
Note that I am assuming that you are using the standard C++ std::string class. If you have done some sort of typedef char *string, then everything I said is wrong, and your code does in fact have an error.DISTRO=Arch
Registered Linux User #388732
- 12-28-2010 #3Just Joined!
- Join Date
- Jul 2010
- Posts
- 5
My understanding was that anything declared in a method in C or C++ was placed on the stack and when the method returns, the pointers are restored.
I know this was an issue in C because of interrupts. You could never be certain of the values on a stack because an interrupt could come around and wipe them out. I have first hand knowledge of this scenario. I assumed that this is also the case in C++.
- 12-28-2010 #4
It is true that strVal is allocated on the stack, and it doesn't survive beyond its scope.
However, you are returning a copy of strVal.
More precisely - in the absence of relevant compiler optimizations (and as Cabhan said, assuming this is C++'s std::string and not some other string type), the statement "return strVal" creates a copy of strVal which survives beyond the function itself - long enough for something to be done with that copy. So if you were to call:
You would (naively) expect this to result in two std::string copy operations:Code:std::string a = IntToString(42);
- strVal being copied to IntToString()'s return value
- return value being copied to (a).
Note that those first two copies of the string (strVal and the return value) don't survive for long - but the string data survives because each time it is copied before the source copy is destroyed.
(Compiler optimizations may streamline this a bit: recognizing that strVal is being returned (and therefore assigning straight into the return value copy, or even (a), instead of performing the two copies. Additionally, it's common for optimizations of std::string to share memory between copies of a string - so even if you did wind up copying the string twice and destroying two copies, you're not actually allocating additional copies of the string data or copying the characters within that buffer, you're just changing the value of the string's instance counter.)
This is one of the things that makes C++ a bit nicer to work with than regular C: if you write your classes right, you can use the object's lifetime to nicely manage allocation and deallocation of the resources that object uses.
- 12-28-2010 #5Just Joined!
- Join Date
- Jul 2010
- Posts
- 5
Thank you.
Many thanks to Cabhan and tetsujin.

This is an eye opener for me. I really thought I had an issue here.
Before posting, I attempted to look this up online and in the C++ programming language 3rd edition. If this scenario is documented, I did not find it. If anyone knows where this is documented, please let me know.
Thanks again.


Reply With Quote
