valgrind error "Invalid read of size 4" [duplicate] - c++

This question already exists:
c++ warning: address of local variable
Closed 9 years ago.
Here is my program
int* fun1(void)
{
int n=9;
int *pf=&n;
cout<<*pf<<endl;
return pf;
}
int main(int argc, char *argv[])
{
int *p=fun1();
cout<<*p;
return 0;
}
Compilation and running of program doesn't give any problems but with valgrind it gives message/warning "Invalid read of size 4".
Any help to resolve the warning is most welcome

nis a local variable in fun1() and is no more valid after exit of the function.

Turning my comment into an answer: You are referencing a local variable from outside of a function after that function has returned. This means that even though, while running the program this seems to work because the stack stays untouched between the assignment. If you call other functions between the assignment and the print, it will most likely fail. I say "most likely" because what you're doing is undefined behavior, and can therefor not be predicted.
To fix this particular case: allocate memory for n on the heap inside fun1, and return a pointer to said memory instead of what you have now.

Local variables exists only when the function is active. You're returning pf which is a pointer to a local variable. As soon as you exit the function, the memory that was allocated to the variable is deallocated, this leads to undefined behavior.

You are returning an address of a local variable and valgrind is warning you of that. Accessing this pointer in the main will invoke undefined behavior.

Related

C++: Incoherent deletion from the Stack? [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
I'm trying to understand how to use functions in C++ to return arrays. I want to understand what's going on here. This is my code, that I compile with g++ -Wall return_array.cpp -o return_array
#include <iostream>
int * do_something(int number){
int viz[3] = {1,2,3};
viz[2] += number;
return &viz[0];
}
int main(){
int *viz;
viz = do_something(3);
std::cout << viz[2] << "\n";
return 0;
}
which gave me the following error:
return_array.cpp: In function ‘int* do_something(int)’:
return_array.cpp:4:6: warning: address of local variable ‘viz’ returned [-Wreturn-local-addr]
int viz[3] = {1,2,3};
By my research, the error is due to the fact that I'm trying to access a pointer that has been deleted from the Stack once I leave the function's scope. However, if I run the code with a workaround:
int * do_something(int number){
int viz[3] = {1,2,3};
int *pointer;
viz[2] += number;
pointer = &viz[0];
return pointer;
}
it compiles and runs just fine. Isn't this new pointer in the precise same situation? Once I leave the function, it is out of scope and should be deleted from the Stack, by the same argument as before. What am I missing?
EDIT:
My question here is not whether or not returning the pointer to a local array produces an error. It should and it does. The question is why the pointer that has been assigned to the pointer to the same array does not!
Once control leaves the function, the array is out of scope. It might be erased, it might not. That region of memory might still contain those numbers for a while, and it might not. Trying to read it might work, or it might do anything. This is known as undefined behavior, and it is a difficult thing to detect and a good thing to avoid.

C++ scopes and allocation [duplicate]

This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
If I understand correctly, variables that are not dynamically allocated are supposed to be deleted at the end of their scope.
However, I wanted to try it out with this code (which I think is not correct as I am supposed to use dynamic allocation) :
int* function()
{
int a = 3;
return &a;
}
int main(int argc, char const *argv[]) {
int* a(function());
std::cout << *a << std::endl; // prints 3
}
Why can I still access the value of the variable a by using the pointer returned by the function when it is supposed not to exist anymore ?
a and hence the return value from function has gone out of scope. You are just lucky.
Just be careful and compile with all the warnings enables - and take heed of those warnings.
The fact that you can access the value is pure luck. The code has undefined behaviour (since the variable is destroyed) and the compiler can generate whatever it wants - but you cannot rely on it.

Don't understand the behavior in the example - strcpy() and function returning address of local array [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
#include <iostream>
#include <string.h>
using namespace std;
/*
The functions defined below are attempting to return address of a local
variable and if my understand is correct...the main function should be
getting garbage.
*/
int *test1(){
int a[2]={1,2};
return a; //returning address of a local variable - should not work.
}
char *test2(){
char a[2]={'a','b'};
return a; //returning address of a local variable - should not work.
}
char *test3(){
char a[1];
strcpy(a,"b");
return a; //returning address of a local variable - should not work.
}
char *test4(){
char a[2];
strcpy(a,"c");
return a; //returning address of a local variable - should not work.
}
int main()
{
int *b= test1();
cout<<*b<<endl; //gives back garbage.
char *c=test2();
cout<<*c<<endl; //gives back garbage.
char *d=test3();
cout<<*d<<endl; //this works - why?
char *e=test4();
cout<<*e<<endl; //gives back garbage.
return 0;
}
As far as my understanding goes regarding function calls and memory management this example program baffles me. If I understand things right, the reason why b=test1() and c=test2() don't work is because they are trying to return address of local variables that are wiped off once the stack memory pops the functions out. But then why is d=test3() working?
You got unlucky because the program failed to blow up.
strcpy(a, "b"); in test3 is fundamentally evil, as there is room for 1 character in a, and strcpy is known to copy the one character in the double quote, plus a termination NUL character, which overwrites memory that your program doesn't really have allocated.
One would advise you to turn your compiler warning levels on the highest level they go. Most compilers will politely give you at least a warning message about it.
The reason why you're third example worked can be summed up as "the phase of the moon was right".
All examples are undefined behaviour, because they return references (or pointers) to local variables. Undefined behaviour means that really anything can happen -- including sometimes the right thingTM, i.e. what you actually meant to happen.

different behaviour of returning local char* and char[] [duplicate]

This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 8 years ago.
I guess its a storage/definition difference but still I cant find a straight explanation of the behaviour. I have a function that returns a locally defined char* in two ways:
//Try 1:
char* printSomething()
{
char arr[100];
sprintf(arr, "The data %u", 100);
return arr;
}
//Try 2:
char* printSomething()
{
return "The data 100";
}
When I print the result of the first function It displays nothing (C) or garbage (C++) while on the second it prints the correct data.
I know I should store the data on the heap in cases like this or define static variable but still, how come the first doesnt work while the second does? and also, can I count on the second way to always work?
The first is just undefined behavior because arr is released when the function ends, so you're left with a dangling pointer.
The second works because "The data 100" is a string literal with static storage duration, which means it persists throught the lifetime of the program.
The implicit conversion to char* is deprecated though, and changing the contents will result in undefined behavior. I suggest you return const char* or std::string.
In both cases you returning char*
The first you return a pointer to a local array variable, located on the stack, which no longer exists after you exit the function. and may be rewritten.
In the second you returning pointer to a const string, located on the code segment, and it exist as long as the program is running.

Returning reference of local variables in C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Returning reference to local variable
Can a local variable’s memory be accessed outside its scope?
In the following code
int& h() {
int o=100;
return o;
}
int main() {
int t=h(); //line 1
cout<<t; //line 2
return 0;
}
Why the output is coming as 100 i.e. the value of the local variable of the function and why there is no error in line 1 because the return type of function is int& but we are returning its return value to a int.
You should never return a reference or a pointer to a local variable. It will be destroyed right when the function returns. It may appear to work in some cases because the stack may not yet be overwritten. But it will fail unexpectedly eventually.
It is legal to assign a reference to something to a value of the same type. So in your assignment a copy is made.
The value is 100 because the memory containing it has just been freed and nobody has written anything to it. Here's another example:
int& h() {
int o=100;
return o;
}
int& h2()
{
int o = 10;
return o;
}
int main() {
int t=h() + h2(); //line 1
cout << t;
return 0;
}
If you compile this with no optimization on Visual Studio, the result will be 20 and here's what will happen:
h() gets called, writes 100 to memory, frees it and returns a reference.
h2() gets called and writes 10 to the same place in memory (it has been freed before)
main() computes the sum of 2 values from the same place in memory. Thus, it's 10+10.
Setting int from int & is not an error. It's a valid operation that means "take this reference to some object and copy whatever is there to my local variable".
Return reference local variable - for single thread application /example by Ivan/ is not problem. For multithread application is problem - when diferent threads use function e.g. h(). In this case may be moments, when threads cross used unallocate memory.
Compilers don't necessarily protect against bad and/or undefined behavior.
Check what options you're passing to your compiler.
Compiling your code at codepad.org produces a warning: http://codepad.org/ParI4AOG
In function 'int& h()':
Line 6: warning: reference to local variable 'o' returned