1
int* a() {
  int a_ = 5;
  return &a_;
}

int main() {
  int* p = a();
  return 0;
}

Is a_ (aka p here) allocated on the stack?

cigien
  • 57,834
  • 11
  • 73
  • 112
DutchBro
  • 45
  • 4
  • 1
    C++ doesn't have a notion of the stack or the heap. It does have a notion of automatic memory allocation and dynamic memory allocation. Most implementations take care of automatic memory allocation as a stack, though. The only place to know where `a_` is allocated is to compile this program and see. `p` points to the now-invalid `a_`. `p` is a valid variable. It can exist. You can perform airthmetic on it. You can pass it around. You MAY NOT dereference is, as that is underined behavior. – JohnFilleau Nov 16 '20 at 04:17
  • 1
    Yes, `a_` is stack-allocated in the function `a()`, and when the function returns the memory gets destroyed and `p` is a pointer to invalid memory. (Obligatory asterisk: Strictly speaking, C++ doesn't have "the stack" or "the heap", it has "automatic storage duration" and "dynamic storage duration", which are typically but not necessarily implemented in terms of stacks and heaps.) – Nathan Pierson Nov 16 '20 at 04:18
  • Which compiler are you using that didn't go apoplectic about this? I tried clang + gcc, and both delivered sternly stupid diagnostics about this. – mevets Nov 16 '20 at 04:26
  • @NathanPierson `Yes, a_ is stack-allocated` Not necessarily. My compiler doesn't allocate it on the stack (if optimisation is enabled). – eerorika Nov 16 '20 at 04:29
  • Which stack is the question? When you make a function call, the program creates a stack-frame for the function. Variables that are local to that function with automatic storage duration have memory reserved on the function stack. When the function returns the memory reserved for the function is released for re-use and you may no longer attempt to access any of the values residing there. – David C. Rankin Nov 16 '20 at 05:37

2 Answers2

3

Where is the memory allocated

int a_ = 5;

Automatic storage is allocated for a_,

int* p = a();

Automatic storage is allocated also for p

Note that after a has returned, the duration of the storage that was allocated for a_ has ended and therefore the pointer returned by a is invalid.


That's from C++ and abstract machine perspective. From compiler / language implementation perspective, no memory needs to be allocated at all in this case since no observable behaviour depends on memory being allocated for the variables.

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

Is a_ (aka p here) allocated on the stack?

a_ is allocated on the stack. The variable p is allocated on the stack, too. The pointer value of p is not required to point anywhere in particular, because dereferencing it would cause UB (see Can a local variable's memory be accessed outside its scope? for example).

At least one implementation (gcc 10.2, default options) compiles a() to return nullptr, which renders the question moot of where (the target of) p was allocated.

Code:

#include <stdio.h>

int* a() {
  int a_ = 5;
  printf("&a_ = %p\n", &a_);
  return &a_;
}

int main() {
  int* p = a();
  printf(" p  = %p\n", p);
  return 0;
}

Output:

&a_ = 0x7ffe7905ed9c
 p  = (nil)

[ EDIT ] To be pedantic, "allocated on the stack" should be read as "allocated on what's commonly referred to as stack, if one exists at all, and if the variable was actually allocated in memory as opposed to, for example, stored in registers or optimized away".

dxiv
  • 16,984
  • 2
  • 27
  • 49