简体   繁体   中英

Stack variables vs. Heap variables

Am I correct in thinking that:

char *buff[500];

... creates a stack variable, and:

char *buff = (char *)malloc(500);

... creates a heap variable?

If that's correct, when and why would you use heap variables over stack variables and vice versa. I understand the stack is faster is there anything else.

One last question, is the main function a stack frame on the stack?

Yes, first one creates an array of char pointers in the stack, about 500*4 bytes and second one allocates 500 chars in the heap and points a stack char ptr to them.

Allocating in the stack is easy and fast, but stack is limited, heap is slower but much bigger. Apart from that, stack allocated values are "deleted" once you leave the scope, so it is very good for small local values like primitive variables.

If you allocate too much in the stack you might run out of stack and die, main as all the functions you execute has a stack frame in the stack and all the local variables to the function are stored there, so going too deep into function calling might get you into a stackoverflow as well.

In general is a good rule of thumb to allocate anything that you use often and is bigger than a hundred bytes in the heap, and small variables and pointers in the stack.

Seeing that you wrote

char *buff = (char *)malloc(500);

you probably meant

char buff[500];    instead of 
char* buff[500];

in your first example (so you have a char-array, not an array of pointers to chars)

Yes, "allocation" on the stack is faster because you just increase a pointer stored in the ESP register.

You need heap-variables if you want:

1) more memory than fits in the stack (generally much earlier)

2) pass memory that was allocated by a called function to the calling function.

Your buff s are not equivalent.

The first one ( char *buff[500] ) is an array of 500 pointers; the 2nd one ( char *buff = (char *)malloc(500) ) is a pointer.

The pointer ( on the stack ) points to 500 bytes of memory (if the malloc call succeeded) on the heap.
The array of pointers is on the stack. Its pointers are not initialized.

Unless using C99, using the stack the size of your array must be known at compile-time. That means you cannot do:

int size = 3; // somewhere, possibly from user input
char *buff[size];

But using "the heap" (dynamic allocation), you can provide any dimensions you like. That's because the memory allocation is performed at run-time, rather than hardcoded into the executable.

The C standard contains neither the words heap nor stack . What we have here instead are two storage durations (of 4 in total): automatic and allocated :

  •  char buff[500]; // note the missing * to match the malloc example 

    within a function declares the object buff as an array of char and having automatic storage duration . The object will cease to be when the block where the object was declared, is exited.

  •  char *buff = malloc(500); // no cast necessary; this is C 

    will declare buff as a pointer to char . malloc will reserve 500 continuous bytes and return a pointer to it. The returned 500-byte object will exist until it is explicitly free d with a call to free . The object is said to have allocated storage duration .


That's all the C standard says. It doesn't specify that the char buff[500] needs to be allocated from a "stack", or that there needs to be a stack. It doesn't specify that the malloc needs to use some "heap". On the contrary, a compiler might internally implement the char buff[500] like

{
    char *buff = malloc(500);
    free(buff);
}

Or it can deduce that the allocated memory is not used, or that it is only used once, and use a stack-based allocation instead of actually calling malloc .

In practice, most current compilers and environments will use a memory layout called stack for automatic variables, and the objects with allocated storage duration are said to come from "heap" which is a metaphor for the unorganized mess that it is compared to the orderly stack, but it is not something that has to be so.

Heap variables can be created dynamically, ie you can ask a size to your user and malloc a new variable with this size.

The size of a stack variable must be known at compile time.

Like you said, stack variable are faster allocated and accessed. So i'll recommend using them every time you know the size at compile time. Otherwise you don't have the choice, you must use malloc()

This is indeed a variable allocated on the stack:

char buff[500]; // You had a typo here?

and this is on the heap:

char *buff = (char *)malloc(500);

Why would you use one vs the other?

  • In char *buff[500] , the 500 needs to be a compile-time constant. You can't use it if 500 is computed at runtime.
  • On the other hand, stack allocations are instantaneous while heap allocations take time (thus they incur a runtime performance cost).
  • Space on the stack is limited by the thread's stack size (typically 1MB before you get a stack overflow), while there's much more available on the heap.
  • If you allocate an array on the stack big enough to take up more than 2 pages of virtual memory as managed by the OS, and access the end of the array before doing anything else, there's the possibility of getting a protection fault (this depends on the OS)

Finally: every function called has a frame on the stack. The main function is no different. It isn't even any more special than the other functions in your program, since when your program starts running the first code that runs is inside the C runtime environment . After the runtime is ready to begin execution of your own code, it calls main just as you would call any other function.

Those two aren't equivalent. The first is an array of size 500 (on the stack) with pointers to characters. The second is a pointer to a memory chunk of 500 which can be used with the indexing operator.

char buff[500];

char *buff = (char *)malloc(sizeof(char)*500);

Stack variables should be preferred because they require no deallocation. Heap variables allow passing of data between scopes as well as dynamic allocation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM