简体   繁体   中英

If I want a global VLA, could I use alloca() in the main function?

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?

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.

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.

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?

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.)

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