|
|
In function 'double*& GetNewPointerRef()': 6:13: warning: reference to local variable 'pointer' returned [-Wreturn-local-addr] |
I was wondering which one would be the better of the three. |
Indeed. The GetNewPointerRef() returns a reference to local variable (in stack memory) 'pointer'. A reference to an object that does not exists after the function returns. |
Lines 7, 21, and 27 are memory leaks. You write to pointers that hold addresses of dynamically allocated memory. You cannot deallocate that memory when you no longer have address stored anywhere. |
|
|
I'm returning a pointer that was allocated on the heap |
storage* pointer = ...
|
|
|
|
Furthermore, there is no difference between a class object and a primitive: |
double * & GetStaticPointerRef() { static double * v; // uninitialized pointer; *v = 1550.85; // error, v is invalid return v; // returns reference to v (but v is static object, so does not vanish) } |
// I've heard of some new kids in the block: std::shared_ptr<double> foo() { return std::make_shared<double>( 3.14 ); } std::unique_ptr<double> bar() { return std::make_unique<double>( 2.718 ); } |
No you're not. Let's look at it: storage* pointer = ... The pointer here, named pointer, is clearly not on the heap. What it's pointing to is on the heap, but the pointer isn't. The pointer is on the stack, and will cease to exist when the function ends. |
storage *& GetStaticPointerRef() { static storage* v; v->value = 1550.85; return v; } The problem with this function? Tell me, what is that pointer v pointing at? |
If I understood it correctly pointer v has not been made dynamically so its contents are on the stack will go away with the pointer as well? |
|
|
v->value
thus looks up from the definition of storage that value should be a double and is at offset relative to start of storage object. However you have not stored any value in v and thus the v->value refers to unknown address (+offset).Pointer is a variable that stores a value, just like any variable. The value is a memory address. The value can be invalid. Value nullptr is know to be invalid. Pointer has dereference operators to access object at the address. |
Reading from invalid address is undefined behaviour, because it is not likely to contain valid object of expected type. Writing to invalid address is undefined behaviour, because it overwrites something. |
static storage*v = new storage |
If you had a storage object, it would be in some block of memory. The storage has member value. It is within that block of memory. The block starts at some address X. The value starts at X+offset. (The offset can be 0.) Your v->value thus looks up from the definition of storage that value should be a double and is at offset relative to start of storage object. However you have not stored any value in v and thus the v->value refers to unknown address (+offset). |
When you write "contents of pointer" you actually mean "the object that the pointer points to". Should mean. |