When do you worry about stack size?

前端 未结 19 987
难免孤独
难免孤独 2020-12-10 12:41

When you are programming in a language that allows you to use automatic allocation for very large objects, when and how do you worry about stack size? Are there any rules o

相关标签:
19条回答
  • 2020-12-10 13:21

    In general, big allocations on the stack are bad for several reasons, not the least of which is that they can cause problems to remain well hidden for a long time.

    The problem is that detecting stack overflow is not easy, and big allocations can subvert most of the commonly used methods.

    If the processor has no memory management or memory protection unit, you have to be particularly careful. But event with some sort of MMU or MPU, the hardware can fail to detect a stack overflow. One common scheme, reserving a page below the stack to catch overflow, fails if the big stack object is bigger than a page. There just might be the stack of another thread sitting there and oops! you just created a very nasty, hard to find bug.

    Unlimited recursion is usually easy to catch because the stack growth is usually small and will trigger the hardware protection.

    0 讨论(0)
  • 2020-12-10 13:25

    my experience: when you use recursive functions, take care of the stack size!!

    0 讨论(0)
  • 2020-12-10 13:25

    I have had problems running out of stack space when:

    • A function accidentally calls itself
    • A function uses recursion to a deep level
    • A function allocates a large object on the stack, and there is a heap.
    • A function uses complicated templates and the compiler crashes

    Provided I:

    • Allocate large objects on the heap (eg. using "auto_ptr foo = new Foo" instead of "Foo foo")
    • Use recursion judiciously.

    I don't normally have any problems, so unfortunately don't know what good defaults should be.

    0 讨论(0)
  • 2020-12-10 13:28

    You start to worry about stack size when:

    • when your program crashes - usually these bugs tend to be weird first time you see them :)
    • you are running an algorithm that uses recursion and has user input as one of its parameters (you don't know how much stack your algorithm could use)
    • you are running on embedded platforms (or platforms where each resource is important). Usually on these platforms stack is allocated before process is created - so a good estimation about stack requirements must be made
    • you are creating objects on the stack depending on some parameters modifiable by user input (see the sample below)
    • when the code executed in a thread/process/task is very big and there are a lot of function calls that go deep into the stack and generate a huge call-stack. This usually happens in big frameworks that combine a lot of triggers and event processing (a GUI framework; for example: receive_click-> find_clicked_window-> send_msg_to_window-> process_message-> process_click-> is_inside_region-> trigger_drawing-> write_to_file-> ... ). To put it short, you should worry about call-stack in case of complex code or unknown/binary 3rd party modules.

    sample for modifiable input parameters:

    in my_func(size_t input_param)
    {
      char buffer[input_param];
      // or any other initialization of a big object on the stack
      ....
    }
    

    An advice:

    • you should mark the stack with some magic numbers (in case you allocate it) and check if those magic numbers will be modified (in that case the stack will not be enough for the task/thread/process and should probably be increased)
    0 讨论(0)
  • 2020-12-10 13:29

    When you are programming in a language that allows you to use automatic allocation for very large objects ...

    If I want to allocate a very large object, then instead of on the stack I might allocate it on the heap but wrapped in an auto_ptr (in which case it will be deallocated when it goes out of scope, just like a stack-resident object, but without worrying about stack size).

    ... when and how do you worry about stack size?

    I use the stack conservatively out of habit (e.g. any object bigger than about 512 bytes is allocated on the heap instead), and I know how big the stack is (e.g. about a megabyte by default), and therefore know that I don't need to worry about it.

    Are there any rules of thumb for reasoning about stack size?

    • Very big objects can blow the stack
    • Very deep recursion can blow the stack
    • The default stack size might be too big (take too much total memory) if there are many threads and if you're running on a limited-memory embedded device, in which case you might want to use an O/S API or linker option to reduce the size of the stack per thread.
    0 讨论(0)
  • 2020-12-10 13:30

    When deciding whether to allocate objects on the stack vs. the heap, there are also perf issues to be taken into consideration. Allocation of memory on the stack is very fast - it just involves moving the stack pointer, whereas dynamic allocation/deallocation using new/delete or malloc/free is fairly expensive, especially in multithreaded code that doesn't have a heap per thread. If you have a function that is being called in a tight loop, you might well err on the side of putting larger objects on the stack, keeping all of the multithreading caveats mentioned in other answers in mind, even if that means having to increase stack space, which most linkers will allow you to do.

    0 讨论(0)
提交回复
热议问题