17

I had a quiz on the memory allocation topic, and this question came across that got me confused as I am not satisfied with the answers. (the Question)

As I have learned, we can create an "Object" on Heap by creating a pointer variable to point to the memory that we have allocated on Heap (using new keyword).

For a specific example:

double* a = new double(-1.0f); 

The Variable a is a pointer and is created on the Stack point to a memory on the Heap. So actually, saying a is allocated on the heap is wrong. Is my understanding is correct?

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • 6
    You are right, `a` is indeed stored on the stack. However from this point of view, every local variable is stored on the stack, only some of them can point to the heap. – Jeysym May 16 '19 at 07:24
  • Thank for commenting! That is what I'm thinking –  May 16 '19 at 07:29
  • 9
    That's correct, *but*: informally, programmers often use the name of the pointer variable when speaking about the object it points to. It's simpler, and the meaning is usually clear from the context. – molbdnilo May 16 '19 at 07:31
  • 8
    Regarding the quiz: All those _variables_ are indeed "on the stack" - if the quiz answer says otherwise, it is wrong (or the question is worded incorrectly). What the question apparently _meant_ to ask is different (although asking whether a reference to something lives anywhere is kind of moot and muddies the whole question). – Max Langhof May 16 '19 at 08:03
  • 1
    [To me](https://godbolt.org/z/ly6QVE) it looks like those variables are "allocated" **nowhere** (although the stack pointer moves around, and `new` and `new[]` get called) – Caleth May 16 '19 at 08:47
  • 2
    @Caleth: the stack pointer moves to align RSP by 16 before a function call; that 8 bytes is unused, and so is the 128 byte red zone below RSP. Your example doesn't use any of the variables (holding the results of those function calls), so yes of course they get optimized away. Until the next `call`, though, each one is effectively allocated in RAX, the return value of the previous `new`. Optimizing compilers do register allocation of C++ variables, so yes depending what you do with `a` the pointer value might never be stored in stack memory. – Peter Cordes May 16 '19 at 12:01
  • 1
    But if you *did* take the address of `a`, the compiler would allocate space on the stack for it. The fact that this doesn't happen in optimized code that doesn't take the address is merely the as-if rule in action. – Peter Cordes May 16 '19 at 12:02
  • 1
    @PeterCordes none of the *values* in the source make it into `rax`, whether you call that a register allocation or not doesn't really matter. I actually was expecting to see some `mov`s and say something like "neither, they are allocated directly in register(s)" – Caleth May 16 '19 at 12:12
  • 2
    @Caleth: when `call _Znwm` returns, `double* var3` is in RAX. It's "dead", though, because the variable is unused. The compiler may not even be "thinking" of it as `var3` being RAX, it probably just optimized away `var3` (e.g. `-fverbose-asm` doesn't print `var3` in the comment, just the empty string). But it has to keep the call to `operator new double()` because `new` is replaceable and so the call is a visible side effect. (And so is leaking 8 bytes of allocation). If you wanted to see something, use `volatile double *var3` (it will spill to memory). – Peter Cordes May 16 '19 at 12:16

2 Answers2

15

a is a pointer with automatic storage duration.

It points to a double which has dynamic storage duration.

It's your job to call delete a; before you lose a pointer to the dynamic memory; typically when a drops out of scope.

(Informally speaking, and talking of typical implementations of C++, you can say that a is on the stack and it points to memory on the heap.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Thank for giving time answering my question! As I interpreted you answer, formally, there is no such thing as **Variable allocated on Heap** there only **Memory allocated on Heap**. Right ? –  May 16 '19 at 07:19
  • 7
    @kevinvu Formally, there does not exist anything like _stack_ or _heap_ in the C++ Standard. Both are just implementation issues. A relevant question: [Are there stackless or heapless implementation of C++?](https://stackoverflow.com/q/10900885/580083). – Daniel Langr May 16 '19 at 07:46
  • 4
    @kevinvu Anyway, there is really no such thing as a _variable allocated on heap_. A _variable_ is just a name that exists only at compile time. At runtime, there are _objects_ (instances of some type). Objects can be (by the implementation) placed, for example, on the stack or on the heap. In the second case, some memory needs to be dynamically allocated and, then, the object needs to be constructed there. Allocation and constructions are two different things, as well as destruction and deallocation. – Daniel Langr May 16 '19 at 08:00
3

You seem to have understood. There is a float on the heap* and a pointer on the stack*. The disagreement is 'just' a naming convention for how you refer to the float.

Some people talk of things-that-are-pointed-to in terms of the-thing-that-does-the-pointing. I am inclined to agree with you: this is potential confusing, and can add complexity.

However in the interest of fairness: keep in mind different people have different motivations for the way they use language. If you never want to deal with pointers and they are just a way of having a variable persist outside of its scope then seeing (*a) as the variable and remembering it obeys slightly different rules is not completely without merit.

[*] Modulo grammar/standards nazisim.

ANone
  • 202
  • 1
  • 4