I have a main
function for my app, and I allocate, for example, paths to configuration files, etc. Currently I use malloc
for them, but they are never freed and always available for use throughout the lifetime of the app. I never even free them because the OS already automatically reclaims allocated memory when an application terminates. At this point, is there any reason not to use alloca
instead of malloc, because the program ends when main
returns and alloca
memory is only deleted once the function it was allocated in is freed. So based on this logic, memory allocated in the main function with alloca
is only deallocated once the program ends which is desired. Are these statements correct, and is there any reason not to use alloca
(alloca is bad practice so when I said alloca meant alloca or making a VLA in main
) in main
for a 'global VLA' like object that lasts until the program terminates?

- 3,119
- 19
- 19
- 37
-
`alloca` is non-standard. and `alloca` is deallocated when the current stack frame dies - i.e. when the function that called `alloca` returns. You should always `free` your `malloc`'d memory, btw. – Raildex Jun 28 '21 at 07:46
-
@Raildex But what if that function is `main`? – user16217248 Jun 28 '21 at 07:48
-
3Stacks are relatively small. The very fact that it is `main` makes it even worse to use `alloca` as it will permanently use up that precious stack space. – kaylum Jun 28 '21 at 07:49
-
@kaylum Half year later, Happy 2022, what if the *amount* being allocated is usually relatively small such as <= 100 bytes? – user16217248 Jan 28 '22 at 04:24
4 Answers
You can use alloca/VLA in main, but why?
The typical reason to use them is if you have some performance sensitive part that is called a lot, and you don't want the overhead of malloc/free. For main, your data is allocated once at the beginning of the program, so the overhead of a few malloc calls is negligible.
Another reason to not use alloca/VLA's in main is that they consume stack space, which is a very limited resource compared to heap space.

- 36,249
- 2
- 81
- 97
-
-
@user16217248 Yes, for data. For code memory is allocated separately and does not belong to these sections (typically by memory mapping the executable). – janneb Jun 28 '21 at 07:57
-
Depends on how much memory you need. If it is small enough (say a few hundred bytes or so), you can safely do alloca
in main()
or use VLAs.
But then, if the sizes of these arrays have a known upper-limit which is not very large, it would be even better and safer to declare them globally with that upper-limit as the size. That way you don't consume stack space and you don't have to malloc
and then ensure the allocation succeeded. It is also then clear to whoever is reading that this piece of memory lives as long as the program does.
If the sizes can be arbitrarily large then the best thing to do is to continue using malloc()
like you are already. Btw even if you are calling malloc()
in main()
and use it for the lifetime of the program, it is still considered good practice to free it before exit.

- 2,177
- 11
- 15
-
So I should make an `atexit` handler, and put `free(ThePtr)` in it? – user16217248 Jun 28 '21 at 08:03
-
1@user16217248 Generally it is good practice to have the same module that allocated the memory clean up after itself. So if you allocated memory in some `foo_init()` function, then there should be a corresponding `foo_cleanup()`. You can use `atexit` but there's generally no need. Just call the clean up function manually. – Lundin Jun 28 '21 at 08:29
-
@Lundin However, in my case it is not possible, due to the nature of my program – user16217248 Jun 28 '21 at 08:30
-
1@user16217248 Sounds like a strong indication of problematic program design then. – Lundin Jun 28 '21 at 08:32
-
@Lundin `NSApplicationMain` does not return, and that is what my application uses, see [this](https://stackoverflow.com/questions/68059359/why-i-cannot-include-appkit-in-pure-c-even-though-i-can-declare-the-functions-m) – user16217248 Jun 30 '21 at 21:41
Technically no, because any variable declared in a function will not be global. But you can do something like this:
char *buffer;
int main(void) {
char buf[size];
buffer = buf;
That would give you an interface to access the buffer globally.
At this point, is there any reason not to use alloca instead of malloc
This is one question that typically should be asked the other way around. Is there any reason to use alloca
instead of malloc
? Consider changing if you have performance issues, but if you just want to avoid using free
, I'd say that's a bad reason.
But I don't really see the point here. If you have an allocated buffer that you want to live from when the program starts to when it ends, then just free it in the end of the main function.
int main(void) {
char *buf = malloc(size);
// Do work
free(buf);
}
I wrote a long answer about alloca
and VLA:s that you might find useful. Do I really need malloc?

- 30,332
- 17
- 55
- 95
VLA (as defined by the standard) and non-standard alloca
are both meant to be used for allocating temporary, small arrays at local scope. Nothing else.
Allocating large objects on the stack is a well-known source for subtle & severe stack overflow bugs. This is the reason you should avoid large VLA and alloca
objects. Whenever you need large objects at file scope, they should either be static
arrays or dynamically allocated with malloc
.
It should be noted that stack allocation is usually faster than heap allocation, because stack allocation doesn't need to concern itself with look-ups, fragmentation and other heap implementation-specific concerns. Stack allocation just says "these 100 bytes are mine" and then you are ready to go.
Regarding general confusion about "stack vs heap" please see What gets allocated on the stack and the heap?
You can't even place a standard VLA at file scope, because the array size needs to be an integer constant expression there. Plus the standard (C17 6.7.6) explicitly says that you aren't allowed to:
If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.
As for alloca
it isn't standard C and bad for that reason. But it's also bad because it doesn't have any type safety, so VLA is preferred over alloca
- it is safer and more portable.
It should be noted that the main purpose of VLA in modern programming is however to enable pointers to VLA, rather than allocating array objects of VLA type, which is a feature of limited use.
I never even free them because the OS already automatically reclaims allocated memory when an application terminates.
While that is correct, it is still considered good practice to call free() manually. Because if you have any heap corruption or pointer-related bugs somewhere in the program, you'll get a crash upon calling free(). Which is a good thing, since it allows you to catch such (common) bugs early on during development.
(If you are concerned about the performance of free(), you can exclude the free() calls from the release build and only use them in debug build. Though performance is rarely an issue when closing down the program - usually you can just shut down the GUI if any then let the program chew away on clean-up code in the background.)

- 195,001
- 40
- 254
- 396