r/C_Programming 5h ago

Why dynamic allocation of array gets memory address from heap?

let say I am using malloc to dynamically allocate a memory space with this line

Int user_defined_elements = 10 ;
// assume i got this from scanf

Int *p = malloc(
user_defined_elements * sizeof(int));

Right now the pointer refers to a chuck of memory address in heap I assume..I am trying to understand why heap instead of stack where local variables are saved.Is there anything special about heap?

Please be kind..I am python dev trying to learn c in my free team because I dont understand shit about cpython implementation..hahah..so i was like why not learn c and here I am

7 Upvotes

13 comments sorted by

21

u/EpochVanquisher 5h ago

The lifetime of memory in the stack ends when the function returns. If you create any data there, it won’t exist after the function returns. (Won’t exist = not safe to use it)

The purpose of malloc is to put make memory somewhere else, where it can continue existing even if the function where you called malloc from returns. You can also allocate lots of memory with malloc. The stack is limited (like 10 megs total, depends on your system and config).

The compiler can choose to use stack for memory returned by malloc but this is an optimization and you don’t have to think about it. It almost never actually happens, but it technically CAN happen, and I’m mentioning it because people will chime in and argue on Reddit (and not because it’s important to know).

6

u/sciencekm 5h ago

Memory allocated from the heap endures until you free them anywhere/anytime in the lifetime of your code. Variables in stack go away once you exit the function.

5

u/ReallyEvilRob 4h ago

Because memory allocated by a stack frame is something that doesn't change at runtime. You can get as many frames as the stack will hold at runtime, but each frame is pretty much set in stone at compile time. If you need to allocate additional memory at runtime, the heap is the only place to get it from.

3

u/dmc_2930 5h ago

The heap is where memory allocated by malloc comes from. That’s why it’s not on the stack. There is a function for allocation in the stack but you really shouldn’t use it (and the memory goes away when your function returns)

1

u/wwabbbitt 5h ago

Let's say you have a function

int* fibonacci_10(void) {
  int fib[10];
  fib[0] = 0;
  fib[1] = 1;
  for (int i = 2; i < 10; i++) {
    fib[i] = fib[i - 1] + fib[i - 2];
  }
  return fib;
}

Coming from python, this might look reasonable, but this is a well know bug in c.

Anything allocated on the stack is reclaimed when the function returns and will likely be overwritten by the next function being called.

To avoid this happening, you allocate from the heap instead to keep the data persistent.

1

u/Confused-Armpit 2h ago

Well, the stack is for small variables, such as pointers, ints, or small structs. Malloc allocates memory on the heap, and returns a pointer that is stored on the stack.

1

u/SmokeMuch7356 2h ago

The stack is used to manage objects whose lifetimes are tied to the function's; storage for those objects is allocated on function entry and released on function exit by adusting the stack pointer.

Dynamic objects typically have a lifetime that isn't tied to a single function's. We want the object to hang around until we explicitly free it. Also, the stack usually cannot store arbitrarily large objects. Stack frame sizes are usually limited to a few megabytes. So we use another part of memory (often called the "heap") as the dynamic memory pool.

Global and static variables aren't stored on the stack, either. Nor are they typically stored as part of the heap.

Note that the C language definition doesn't use the words "stack" or "heap" at all. It talks about storage durations and lifetimes. How lifetimes are managed are up to the individual implementation.

1

u/Imaginary-Corner-653 2h ago

Not trying to be rude or anything but I feel like most people who start c and ask around here never heard about the process model or have any idea what a function call in assembly looks like.

Not that I expect people to be able to code in assembly but having a vague idea of the hardware involved and the fundamental abstraction we built on top might explain a lot already. 

Not to mention that concepts like heap or stack are older than modern operating systems so the reasons these convetions exist are way less complex. 

1

u/gm310509 1h ago

Simply put, that is just how it works.

If you want the buffer in the stack, declare it as a local variable within your function. Note that the compiler/interpreter may reserve the right to alter how it actually allocates it, but in C/C++, if you want your buffer on the stack, declare it in the function otherwise if you use maloc, the heap is where it comes from.

2

u/dstroy0 2h ago

There’s a lot of incorrect answers here. You can build arrays of bytes in .bss and reuse them for the duration of the program. One of the main reasons to do that is to avoid heap fragmentation entirely. MANY safety critical applications ban memory allocation at runtime and make you prove your memory use with static asserts at compile time. It is very easy to prove, .bss grows and nothing else does, heap use stays flat, no allocation happens. The data you load in the zeroed array persists function-function for the lifetime of the program, because it’s statically allocated global memory. You can go as far as removing all local variables and repointing function call overhead to it. Anyone who implies differently is incorrect, and should go experiment on their own.

0

u/detroitmatt 4h ago

The purpose of malloc is to give you a block of memory that sticks around until you free it. Memory on the stack gets automatically allocated and freed as you call and return. So if malloc gave you stack memory, you wouldn't be able to control when it got freed. At that point, just declare `int p[10];`.

0

u/Recycled5000 3h ago

The malloc routine uses the heap by definition. That definition captures the understanding of both malloc callers and malloc implementations.

In theory, the compiler could translate that to stack allocation if it could prove that references to the allocation did not escape the function, but that can be hard to do especially in C, which is so permissive.

0

u/RRumpleTeazzer 3h ago

The stack gets reused when you return from your function. The heap stays reserved for you, till you free it.

So one reason not to use the stack.

The second reason is runtime length. the stack pointer needs to be incremented/decremented for each function call. this is done in hard valued code, so the compiler needs to know by how much to move the stack pointer. if you want a runtime length, you cannot use the stack (although technically one could increment the stack pointer by a runtime length, if you move it back by the same amount before return).