简体   繁体   中英

Heap vs stack vs bss section

还有什么更好的地方来存储具有恒定预定义大小的运行时数据(如缓冲区):堆(malloc),堆栈(例如,函数内部的char buf[BUFSIZE] )或bss节(全局区域中的char buf[BUFSIZE] )?

It depends on what you want to do with the buffer.

Globals should usually be avoided, you will have to be very careful to not fall over the problems coming with them.

If the buffer is needed in only one function and BUFSIZE is not too large (a few KB max), you can make it local. However, keep an eye on total stack usage, as nested calls add up. A static local is only needed when you want to keep the values between calls, effectively making it a global with local scope. But it will give you headaches when you go multi-threading or want to use recursion.

If the buffer is used across function calls or BUFSIZE is quite large, then use malloc()/free(). If the function is called often, it may be a good idea to allocate it once outside of the function, do all the function calls, and then free it, instead of allocate and free another buffer for each function call. But this is near premature optimization, because it unnecessarily couples the internal structure of the function with the outside caller.

In the bigger picture, when your program grows, you want to give it more structure and clearly define responsibilities, esp. for memory handling, else you will eventually lose track. This buffer is a working detail of a specific module with a specific task. A typical approach is to use a struct to organize data in an OOP way, with a create and destroy function to allocate and free such an object. The buffer could then be part of this struct.

struct s_foo
{
    char buf[BUFSIZE];
    ...
};

struct s_foo *foo_create (...);
void foo_destroy (struct s_foo *foo);
void foo_action (struct s_foo *foo);

This allows you to have any amount of foos in parallel, each with its own buffer, independent from each other. Additionally, the buffer content is kept between calls without the headaches of a static variable.

In this case, if the buffer is not shared between functions, IMO the best option would be a local static variable:

void func(...) {
    static char buf[BUFSIZE];
}

This avoids both repeated allocation/deallocation and namespace clutter.

EDIT

This solution isn't thread-safe, but global variables aren't either.

You'd want a static variable that's allocated at load time and remains through the life of the program. So option three, the so called "bss" section.

Obviously, heap is out because the size is limited. I wouldn't go for statics either because they are not reentrant and they bring havoc in recursion. So, put it in the stack frame.

void f(...) {
    char buf[BUFSIZE];
}

BTW, its a good practice to avoid statics or globals unless they are absolutely necessary.

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