2

When you return a newly allocated variable through a function , is a copy made and passed and the original deleted automatically?

Im assuming theres no memory leak

#include <iostream>

using namespace std;

int* allocater()
{

    int* x = new int(1);
    return x; 

    // what happens to the memory allocated to x ?
}


int main()
{


int* a = allocater();
int* b = allocater();


cout<<*a<<"  "<<*b;

delete a;
delete b;

// all memory allocated has been deleted?

}

the output is as expected.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
visitor
  • 111
  • 5
  • 2
    `x` is local variable on stack, so it is deallocated automatically. If you are asking about the memory from `new` then you might need to consult a [good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) on meaning of pointers. – Quimby May 02 '19 at 22:07
  • 1
    When you return a raw pointer, the only thing that gets copied is the pointer. The original pointer is popped off the stack, but the memory you allocated remains untouched. – Alecto Irene Perez May 02 '19 at 22:07
  • 1
    `x` is local, but no one has freed memory (`delete`d it), so returned pointer is a valid one. – J. S. May 02 '19 at 22:12
  • Into `allocater()`, `int* x` is a local variable which points to a block of memory of size `int` which was reserved using the keyword `new int(1)`. The memory will be reserved until: The program finishes or uses the pointer to release that block of memory, using `delete`. So, in the case the program keeps running without release the block of memory, it could be considered as a Memory Leak. In your case, your are right, there is no memory leak because you are released the memory from pointer `a` and `b` which were allocated at the moment of invoke the function `allocater()`. – Jorge Omar Medra May 03 '19 at 05:06
  • 1
    Please learn to write declaration with white space following grammar. Since grammar of a declaration is TYPE DECL it should be written `int *x` not `int* x` which would suggest another grammar. I suppose you don't write `a+b * x` as it would strange! – curiousguy Jun 01 '19 at 23:49

5 Answers5

5

When you return a newly allocated variable

Objects with dynamic storage are not variables.

There is a variable in the function. It's named x. The type of the variable x is int* i.e. it is a pointer to an integer.

is a copy made and passed and the original deleted automatically?

x is an automatic variable so it is destroyed automatically when it goes out of scope. The variable is indeed copied as a return value into the calling expression - although, it is possible for the compiler to elide this copy, if it performs named return value optimisation. That is useful if the type is big, or slow to copy (which a pointer isn't).

The objects with dynamic storage (whose type is int in your program) are not destroyed automatically. They must be deallocated with a delete expression.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

Whenever memory is allocated like this, it is reserved on "The Heap". This is an area of memory allocated to your program by the operating system. By using the allocation functions in C++, e.g.: new() or malloc() (there are others too), a contiguous block of this heap is reserved, and the address of it (a pointer) is returned to the calling code.

So in your function:

int *allocater()
{
    int *x = new int(1);
    return x; 
}

A single integer-sized piece of memory is reserved (probably 4-8 bytes), and the address of this memory is returned. This address is just a number, when the number is interpreted as a location in memory, it's called a pointer - but it's still just a number.

So when your function returns, the memory is still allocated on the heap. If your program forgets that number, this memory is "leaked" - you program cannot de-allocate it with delete(), delete[]() or free() because you don't have the number to tell the de-allocation function where to free.

In your code, because you store the return value from allocater(), it's possible to de-allocate the block with delete. So you code works fine, and the memory is de-allocated properly.

Kingsley
  • 14,398
  • 5
  • 31
  • 53
0

Nothing happens until you free it. Yep, that's a valid code and there are no leaks.

In C++11 (or earlier auto_ptr-s) there were introduced RAII pointers: unique_ptr, shared_ptr, etc. So if you use them:

int* allocater()
{
    auto x = std::make_unique<int>(5);
    return x.get();  // getting raw ptr
}

it becomes invalid, because delete is called when x is destroyed and this happens when you exit allocater.

J. S.
  • 425
  • 4
  • 13
0

C++ doesn't have Garbage collector. When you create a local object, the memory is allocated on the stack and when they go out of scope, the compiler calls the destructor automatically (depends if the object is non-trivial) and frees the memory after return.

However, sometimes you need to allocate the memory dynamically. In this case, we can use new and delete to allocate and delete the memory explicitly. However, from C++11 smart pointers are introduced which are just a wrapper around the raw pointer. This helps in managing the life time of the objects.

The problem with raw pointers is that programmer has to explicitly destroy the object when it is no longer useful.

However, this is automatically take care by smart pointers.

So in your code, x is a local variable and as soon the function returns. The x is destroyed but not the memory it points to.

cpp_enthusiast
  • 1,239
  • 10
  • 28
-1

Many thanks for your very informative responses and feedback, really helped clarify things, using pointers feels like a game of pass the parcel!

so as long as the allocated memory has some pointer pointing to it - it can be deleted without a leak, be it returned from a function or in the main

Many Thanks

visitor
  • 111
  • 5