Why does an object go out of scope when passed as a pointer, but not when it is returned

difference between return by value and return by reference in c++
return by pointer in c++
c++ return by reference vs pointer
c++ function return pointer to object
return by reference in c++ - geeksforgeeks
difference between call by reference and return by reference in c++
c++ return reference to object
return by reference in c++ in hindi

Making a very simple linked list I found myself confused about what is probably a very simple scoping concept. The first works as expected. It would seem that in the second makeNode function the node "n" is going out of scope at termination. I'm confused why this is happening.

I'm pretty sure the allocated memory is still there, and both methods have a pointer to that memory. So why is one not working?

the Program has two make node functions

#include <iostream>
using namespace std;

struct Node
{
    int value;
    Node* next;
    Node() : next(NULL){}
};

Node* makeNode1(int value)
{
    Node* n = new Node;
    n->value = value;
    return n;
}

void makeNode2(int value, Node* mountPt)
{
    Node* n = new Node;
    n->value = value;
    mountPt = n;
}

void destroyNode(Node* mountPt)
{
    if(mountPt->next != NULL)
    {
        destroyNode(mountPt->next);
        delete mountPt;
    }
}

int main() {
    Node* origin = NULL;

    // This works
    origin = makeNode1(4);

    // causes a runtime error when dereferenced
    makeNode2(4, origin);

    return 0;
}

For makeNode2 the pointer parameter mountPt is passed-by-value itself, then any modification on the pointer itself inside the function like mountPt = n; has nothing to do with the original argument origin.

You can change it to pass-by-reference, i.e.

void makeNode2(int value, Node*& mountPt)

Problems with pointers: out of scope, out of mind � The Colin Walls , Some key things do not change: the object z still has a scope and when the object is created and when it is destroyed, which occurs on return� The destructor for the object which goes out of scope (the Foo*) gets called, but the one for the pointed-to object (the Foo you allocated) does not. Technically speaking, since you are in the main, it is not a memory leak, since you up to when the application is not terminated you can access every allocated variable.

In the first instance, you are creating a new section of memory with a pointer to that section of memory (which is just an address) and then returning that address. The second example passes in a pointer to an address in memory and then reassigns that address (i.e. changes that value) in the scope of the function. However, the value of that pointer (the address it refers to) reverts back to its previous call once the function exits as the pointer has a value on the stack already. The difference is in the first call you change the value stored in the address that is ultimately passed out of the function, while in the second you change the address that the pointer is pointing to, but that pointer goes back to pointing to the old address once you change scope back to the main body.

7.4a — Returning values by value, reference, and address, This works because dynamically allocated memory does not go out of scope at Smart pointers (covered later) and types that clean up after themselves should be When returning a member of an object that was passed into the function by� const & parameters are generally to 1. promise not to change the value 2. keep from making a copy for the function call. It does not necesarily indicate that the reference will be kept. – crashmstr Sep 30 '15 at 12:04

Change the function for the following:

void makeNode2(int value, Node* mountPt)
{
    Node* n = new Node;
    n->value = value;
    if(mountPt) delete mountPt;
    mountPt = n;
}

where if mountPt was already allocated, it will be freed, and then origin could point on the allocation n

In C++, if I allocate new memory on the heap using the new function , Yes, the pointer will go out of scope, BUT you will forever lose that pointer to the If you are allocating an object (not an array), using eg: How would I delete a pointer in C++ that has been passed to a function and I don't know how it was allocated? So if you are returning the pointer connected to the dynamically created� The C++ new operator does indeed return the address of the newly-created object. The new operator does not create a separate pointer variable. It allocates a block of memory, calls constructors (if any), and returns to you the address of the block

X-Y solution: eliminate the need for a makeNode function by expanding the Node constructor

struct Node
{
    int value;
    Node* next;
    Node(int val = 0) :value(val), next(NULL){}
};

Usage

Node * origin = new Node(4);

DCL30-C. Declare objects with appropriate storage , Every object has a storage duration that determines its lifetime: static, thread, automatic, or allocated. Do not attempt to access an object outside of its lifetime . The assignment itself is valid, but it is invalid for c_str to go out of scope while p In this noncompliant code sample, the function init_array () returns a pointer to a� The answer is to make one of the pointers weak. Remember that an object is destroyed if a weak pointer is the only reference to it. To do anything with a weak pointer, however, you should first convert it to a shared pointer by calling the lock () method. The resource can then be safely manipulated if the value returned is not null.

While all above - including the accepted answer - are relevant, none directly point to the actual logical flaw. Instead of mountPt = n;, you need mountPt->next = n;.

MEM31-C. Free dynamically allocated memory when no longer , Before the lifetime of the last pointer that stores the return value of a call to a In this noncompliant example, the object allocated by the call to malloc() is not MEM31-C-EX1: Allocated memory does not need to be freed if it is assigned to a Finds resource leaks from variables that go out of scope while owning a resource. This works because dynamically allocated memory does not go out of scope at the end of the block in which it is declared, so that memory will still exist when the address is returned back to the caller. Keeping track of manual allocations can be difficult.

smart pointers, Smart pointers are used to make sure that an object is deleted if it is no longer So, in the example above, it does not matter if the function scope is left through the return statement, or it can be created without a pointer and assigned one later If you try to copy a unique_ptr<> , you'll get compiler errors. If this value is not assigned to anything, the temporary return value will go out of scope and the Resource will be cleaned up. If it is assigned (as shown in main()), in C++14 or earlier, move semantics will be employed to transfer the Resource from the return value to the object assigned to (in the above example, ptr), and in C++17 or newer

std::unique_ptr, Freestanding and hosted implementations unique_ptr::get and disposes of that object when the unique_ptr goes out of scope. the requirements of MoveConstructible and MoveAssignable, but not it is limited to the scope in which the pointer was created. returns a pointer to the managed object No other pointer can point to that object. When a unique_ptr goes out of scope it automatically deletes the object it was pointing to. shared_ptr has shared ownership over an object. When all shared_ptrs go out of scope, it deletes the object. Internally it just keeps a counter of how many shared_ptrs there are pointing to that object.

Top 10 Most Common C++ Mistakes That Developers Make, In this article, we are going to take a look at some of the common mistakes that are it will be deleted as soon as the program execution exits from the scope. There is no guarantee for every compiler that a pointer to an array will point to the but after the function returned the stack was unwrapped and all local objects� A C++ program can be made easier to read and maintain by using references rather than pointers. A C++ function can return a reference in a similar way as it returns a pointer. When a function returns a reference, it returns an implicit pointer to its return value. This way, a function can be used on the left side of an assignment statement.

Comments
  • Open the chapter in your C++ book that explains the difference between passing function parameters by value, versus passing them by reference, and read it. You're passing it by value, and makeNode2 leaks memory. The pointer passed to is is not initialized, and it remains uninitialized in the caller, because it was passed by value. That's how C++ works.
  • There is a leak in makeNode2, you should add the line if(mountPt) delete mountPt; to make sure to delete previous allocation first, and then its okay to assign n.
  • Vuwox is correct.
  • @Amadeus Yes, I understand that the above compile, but without the delete, this function create a memory leak. And by adding it, compiler will not gives parameter 'mountPt' set but not used will using full warnings level, and also the runtime error won't append either.
  • Note that doing this causes a memory leak; the original origin pointer allocated in makeNode1 gets replaced by the new one allocated in makeNode2 without being delete-ed.
  • I'm aware. Obviously only one function is needed. I was simply showing both configurations.
  • Passing a pointer by value will still allow you to permanently change the value stored at an address, but does not allow you to change what the pointer points to.
  • "reverts back" is a poor way to describe it. The source never changes at all.
  • I agree that this would be better memory management, but won't this have the same scope issue?
  • @mreff555 Yes it would.
  • It actually doesn’t. But if a reference operator is appended to the Node* parameter, as mentioned above, it works