Dangling pointer: reference to local variable not destroying [duplicate] - c++

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 1 year ago.
While reading about the dangling pointers, I came across some examples and concepts of dangling pointers. Basically, Dangling pointers are those pointers that used to point to some valid memory address but that memory address is no longer valid(local variables, releasing the memory).
So I tried the example:
int* fun(){
int a=100;
return a&;
}
int main() {
int *a =fun();
printf("fun %d",*a);
}
Which gives the error that: address of local variable is returned and it is in sync with dangling pointer concept.
But I slightly modify this code to:
int* fun(){
int a=100;
int* var=&a;
return var;
}
int main() {
int *a =fun();
printf("fun %d",*a);
}
This one works without any error.
My doubt here is that, fun() returns a int pointer and this pointer contains the address of the local variable a. After the function returns back the memory of a should be released then why does this code works without any error.
Also on my system this following don't work:
int main() {
int* x;
{
int y = 3;
x = &y;
}
*x = 56;
printf("jsdf");
}
This being the standard example to demonstrate dangling pointers.
Any one please let me know where my thinking is wrong and what happening behind the scene.
PS: I am using windows10, MinGW compiler with VSCode.

First two examples are equivalent, and in all examples a dangling pointer is used. The compiler doesn’t show you the error in the second example because it is not required to do so, but it is nevertheless invalid, its behavior is undefined. And undefined means undefined, i.e. anything is allowed, including seemingly valid behavior, but more likely data corruption, crashing, or whatever (a.k.a. nasal demons).

Related

Passing the pointers by refrence?

**So recently i came up with a question in an interview it was based on pointers**
void fun(int *p){
int q = 10;
p = &q;
}
int main() {
int r = 20;
int *p = &r;
fun(p);
cout<<*p<<endl;
}
*my question is
(1)Justify the result w.r.t the memory allocation like how this is happening?;
(2) how to pass this pointer variable by refrence (i wrote *&p in the parameter of void fun()) when i did it i observed that the p is printing a garbage value ,Now first i thought may be fun has different memory allocation and when it takes the address of q from fun function it address changes but that address in main function is pointing to some garbage value ,Am i right and please explain?
void fun(int *&p) {
int q = 10;
// here the object q began its existence
p = &q;
// here you pass the address of that object *out*
// of the function, to the caller
// here the object q ceases to exist
// question: does anyone have now-invalid pointers that
// pointed to that object?
}
You'll of course immediately see that yes, the caller of fun has a pointer that doesn't point to a valid object (objects that don't exist are by definition invalid). This is undefined behavior. Anything can happen.
Whatever you observe is just as good as what anyone else would observe :) I can make this code pretend to work, or pretend fail on almost any compiler - it's only a matter of arranging things in a certain way. That doesn't make the code any more valid, of course, and the notion of "working" or "failing" is meaningless anyway: the code is invalid, so as far as C++ is concerned, the discussion about the effects is invalid as well :)

pointers scope questions and return reference of pointer inside vector of pointers encapsulated in class

I have some questions about pointers, scopes and pointers inside vector encapsulated in class
i have this supposed cases and examples with questions:
Example 1
the variable int y scope is inside the function and when the function finish and go away that returning reference will be died and that reference be referenced to nothing?
int& createInt() {
int y = 5;
return y;
}
case1: if i do this in main or other function:
int x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
this mean that im saving my own copy of the value of createInt()
function that is 5 in the variable x, so is safe because int x contain their own value?
but what happen with the reference returning from the createInt() function, is there a memory leak or not because is not a pointer a will die with the scope of the function.
case 2: if i do this in main or other function:
int &x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 32767
int &x is equals to the reference returning from createInt() function, that reference die when the function finish/go away so for that reason
int &x is returning a wrong value 32767 and not 5 or what are that 32767 value?
so int &x = createInt(); is evil and very bad practice because is reference to nothing.
example 2
what about this? i'm requesting allocation memory for int and initialized memory to the pointer variable...
int& createInt() {
int* y = new int(5);
return *y;
}
that pointer variable is in the stack but store a reference to the new int that is in the heap, so that new int will be alive when the scope of the function go away because is in the heap right?
so when i return the reference i'm returning the reference to that new int not the pointer variable, right? so is bad to returning the reference instead of the pointer? for what?
case1: if i do this in main or other function:
int x = createInt();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
i'm creating a copy of the new int value from createInt() in my local int x variable, so is this a memory leak because i'm creating a copy and not getting the pointer, so i can't do a delete of int x variable because is not a pointer, and also i can't delete the int *y pointer created inside createInt() function because the pointer is lost, i don't have it outside the createInt()
but whats happen if i do:
delete &x;
i will get a error:
malloc: *** error for object 0x7ffee204b8c8: pointer being freed was not allocated
because i'm deleting my int x that is not in the heap? or is trying to delete the int *y inside the createInt() function ?
case2: if i do this with the same function:
int &x = createInt2();
std::cout << "x value \n";
std::cout << x << "\n";
// std::cout return 5
my int &x is a reference of the returning by createInt()
so i can do:
delete &x;
is a memory leak here? but its so bad delete &x reference instead of the pointer int *y? maybe doing delete & i'm not have form to be sure if that is allocated memory or is stack memory, so good practice is never try to delete using &?
vectors parts:
i have a class A that contain a vector of pointers of class B, also i have a method that return a element of the vector but as reference (because i want to have it in memory to reutilize it and control when is deleted like a connection pool also i move it from used vector to notInUsevector but this is other history), and in the destructor of class A i delete all the vector elements:
Class A {
//this is singleton
public:
static A& getInstance()
{
std::call_once(m_once, []() {
instance.reset(new Database());
});
return *instance;
}
B& getFirstElement() {
auto element = connections.front();
return *element;
}
~A() {
for(auto element : myVector){
delete num;
}
}
A(A const &) = delete;
void operator=(A const &) = delete;
private:
A();
static std::unique_ptr<A> instance;
static std::once_flag m_once;
std::vector<B*> myVector;
}
so in other place/function/class etc i do:
auto element = &A::getInstance().getFirstElement();
or maybe is best or the same:
auto &element = A::getInstance().getFirstElement();
so when the Class A instance is deleted the destructor will delete all the pointers inside myVector
is this safe, there is a memory leak? it's a very bad return the reference in the getInstance() function instead of the pointer?
thanks
First of all let's make it clear, scope is "layer" between { and }. It might be a function body, statement (if, switch, for, etc.) or standalone scope. The most important consequence is that life time of objects created on stack is limited to that scope.
Take your function createInt() as example, internal int y, exists only inside of that function. The moment you reach } that memory is free.
Second thing is term memory leak. Memory leak is a situation where you have a chunk of memory (might be a single byte, might be a couple of pages) and no way to point at it. It's like a locked box without a key. It is there, it is yours memory, it won't be free unless you tell, problem is you don't know where that memory is located, you have no pointer for it.
That's being said, let's talk about your cases:
Example 1 Case 1:
You are lucky. Your function return its internal y by reference, but this returned variable is freed before you return from your function. Effectively you have a value written down on sticky note, then you throw it to the trash and then return saying that your value is on that note that is in trash. The only reason you can still read it is because no one assigned that bit of memory in the mean time and it was not overwritten. Remember, the moment your function reached } all stack alocated variables (y was allocated on stack) are destroyed. That also answer your second question about memory leak, there is no memory leak. As long as you work with stack, allocation and deallocation is done "automagically" as destructor calls are inserted at the end of the scope (usually) by compiler.
Example 1 Case 2:
The very same thing as in case 1. Your returned value is compromised because you returned stack allocated variable that is no longer valid as you return from function. Now you can observe this because between assigning and reading that value you make a function call. Depending on where original y was allocated that bit of memory might be reused during std::cout call. This become obvious as you work on the very same bit of memory cause of reference usage. Remember when you reached } of createInt(), you free that bit of memory. As an additional excersise, put a break point on lines int &x = createInt(); and int x = createInt(); then step into function and watch memory state as you leave it.
Example 2 Case 1:
Now you create (potential) memory leak. You allocate a memory on heap so it won't be destroyed as you leave function body. You also pass that exact memory address, so you also should take responsibility for freeing it and you don't call delete, so that's your memory leak. And one more problem occurs as you assign returned value to completely new stack allocated variable. Your original x from createInt() is allocated, then returned by reference but feed to assign operator to other independent variable (int x have different address than int* y). Again you can check this with help of breakpoints and debugger.
Example 2 Case 2:
Now this is almost proper use of variables returned by reference and assignment of them. You create variable x on heap, then return it's address and assign it to y. Problem being as x was created on stack you are responsible for destroying it so call to delete is neccessary to avoid memory leak. Put a break point and track memory addresses of both x and y. They are the same.
General rule of thumb is that return by reference should be used only with variables that exist outside of function, for example you can use it for class memebrs as they live inside the object or for global or static variables. For other purposes use return by value, unless you really need that very object, then return it by pointer. And while you work with pointers always be aware that someone at some point have to delete underlying variable.
I skip the part about vectors and instead point you a good tool for tracking memory leaks. It's not the best solution by any means, but for starters it will do the trick (assuming you are using Visual Studio).
https://learn.microsoft.com/pl-pl/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019
Remember to use breakpoints and debugger instead of printing everything to output/console. This will help you a lot. In both tracking memory and variable state, and understanding what your code really does.
I don't have the impression you have a real question at all, because you seem yo have found out all tricks, traps and good practices on your own. You seem to know about memory leaks and dangling references. Static and dynamic allocation. Most of your assumptions seem correct. Some hints though :
* references '&' and raw pointers result in exactly the same machine instructions, but they are hints to the programmers. Indeed, a method returning a reference likely means you don't have to take ownership for that reference, but without documentation there is no guarantee on the lifetime of that object. A raw pointer may represent a heap instance, or an optional argument, but it could also represent just a reference. This lack of ownership rules in C/C++ is indeed tricky.
* When dereferencing a dangling reference, the behavior is undefined. It may be working perfectly on your machine and it could burn my harddisk. Anything goes.
* When dealing with heap allocations, we nowadays prefer yo use smart pointers whenever possible. There is no mistaking in it's usage. Search for unique_ptr and shared_ptr
* Finally I recomy learning a bit of Rust. This is a programming language that was specifically designed to resolve such object lifetime/ownership issues. It is quite easy to install and run the most basic examples. Just try returning a dangling reference with Rust, you'll learn a lot, believe me.

the function of pointer NULL in C++ [duplicate]

This question already has answers here:
Dereferencing a null pointer
(5 answers)
Closed 8 years ago.
class A {
public:
int value = 1;
void foo() { ... };
};
int main() {
A *a = NULL;
int temp = a->value; // Crash!
a->foo(); // OK
}
What happened after I assigned the pointer NULL to a pointer variable? I thought nothing can be done until I allocate a memory to it by new. However, it still can call member function foo(), but crashed when calling member variable.
Could anyone tell me what's going on here? Thanks!
Both invoke Undefined Behavior, irrespective of the behavior you're observing, because when it is UB, anything is possible.
However, one explanation why it does't crash in the second case, possibly because the call:
nullptr->foo(); //a == nullptr, becomes implicit 'this' inside foo()
is translated to:
foo(nullptr); //the implicit 'this' passed as first argument
by the compiler, which seems fine (to the compiler), as you're not accessing any member data inside the function. If you access member data, the chance of getting it crashed increases. The compiler is just being tolerant of your wrongful deeds as long as it can.
de-referencing NULL pointer is undefined behavior. You are unlucky that you got through it in second statement.
In this case, it appears to work because the this pointer, which does not point to a valid object, is not used in foo .If it happened to refer to this there would have been one less post on stack overflow.

C++ function returning pointers make no segmentation fault [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I have made this simple test program:
#include <iostream>
class test {
public:
void print() {
std::cout<<"hello world!"<<std::endl;
}
};
test* getPointer1() {
return new test;
}
test* getPointer2() {
test a;
return &a;
}
int main() {
test* test1;
test* test2;
test1=getPointer1();
test2=getPointer2();
test1->print();
test2->print();
}
For what i know, when you return a pointer to a memory location, and the function ends, the pointer should point to a portion of memory that no longer exists. But i don't seem to be right: when you call test1->print() and test2->print(), istead of getting a segmentation fault, the program prints two time hello world!.
Could you explain me why this occur?
Thank you in advice and sorry for my bad english
test* getPointer1() {
return new test;
}
In the above, test is allocated on the heap and will not be destroyed until you explicitly tell it to do so. So the pointer will remain valid.
test* getPointer2() {
test a;
return &a;
}
In this function, however, you're putting an instance of test on the stack and returning a pointer to an address in the stack. It appears that the second call works because that stack address hasn't been overwritten yet by something else.
Try this main
int main() {
test* test1;
test* test2;
test1=getPointer1();
delete test1;
test2=getPointer2();
test1->print();
delete test1;
test2->print();
}
With this main you handle the memory leak from test1.
But when you do something good (handling the memory leak).
test2 comes crashing down blazing in flames.
Conclusion
Don't return pointers or reference to a local object that will get erased when going out of scope.
For what i know, when you return a pointer to a memory location, and the function ends, the pointer should point to a portion of memory that no longer exists.
No. It points to a portion of memory that no longer contains a valid object. Typically, the memory still exists, and is still accessible; on most platforms, making it inaccessible is either impossible or expensive.
Dereferencing the pointer gives undefined behaviour. In your case, calling the member function doesn't do anything that depends on the memory contents, so you see the function being called as if there were a valid object. You can't depend on that, though - the behaviour is undefined.
test1 should never crash since it creates the object on heap. It persists until you delete it (which you need to do BTW).
test2 could crash since it creates the object on the stack and it is deleted when leaving the function.
It actually does not crash in your case because your software is so very simple. It probably does not overwrite the stack so the zombie object is still functional. In a real world application the object's memory location would be overwritten and it would crash or do something else unpredictable.

what's wrong? dangling pointer? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Returning the address of local or temporary variable
Can a local variable's memory be accessed outside its scope?
#include<iostream>
using namespace std;
int *p = NULL;
void
fun(void){
int i = 10;
p = &i;
}
int
main(void){
fun();
cout<<*p<<endl; //#1
cout<<*p<<endl; //#2
return 0;
}
I think #1 and #2 will output the same, but why #1 output 10 and #2 output a random number?
This is just undefined behavior. You're working with a pointer to a local variable, after that variable has gone out of scope. Anything could happen.
This is indeed a dangling pointer.
You are assigning p to point to an automatic (local) object. Once fun has returned, the object no longer exists, and attempting to access it through p gives undefined behaviour.
If you're interested in why you observe that particular behaviour: on most platforms, the stack frame of fun will still exist until another function is called. So reading p for the first call to << is quite likely to find the old value of i. After calling <<, the old stack frame has most likely been overwritten, so reading p will find an arbitrary value. But none of this is behaviour you can rely on; accessing the dead object could cause a crash, or any other behaviour.
Yes, p becomes a dangling pointer the moment fun() returns.
You are saving a pointer to a variable that is out of scope. Thus, the behavior is undefined. It can print anything, or even crash your application. Or even make your computer explode.
Your function is returning a pointer to something that gets over-written:
int i = 10;
p = &i; // This line
Because i is a local variable.