Why can't we allocate dynamic memory on the stack?

Allocating stuff on the stack is awesome because than we have RAII and don't have to worry about memory leaks and such. However sometimes we must allocate on the heap:

  • If the data is really big (recommended) - because the stack is small.

  • If the size of the data to be allocated is only known at runtime (dynamic allocation).

  • Two questions:

  • Why can't we allocate dynamic memory (ie memory of size that is only known at runtime) on the stack?

  • Why can we only refer to memory on the heap through pointers, while memory on the stack can be referred to via a normal variable? Ie Thing t; .

  • Edit: I know some compilers support Variable Length Arrays - which is dynamically allocated stack memory. But that's really an exception to the general rule. I'm interested in understanding the fundamental reasons for why generally, we can't allocate dynamic memory on the stack - the technical reasons for it and the rational behind it.


    Why can't we allocate dynamic memory (ie memory of size that is only known at runtime) on the stack?

    It's more complicated to achieve this. The size of each stack frame is burned-in to your compiled program as a consequence of the sort of instructions the finished executable needs to contain in order to work. The layout and whatnot of your function-local variables, for example, is literally hard-coded into your program through the register and memory addresses it describes in its low-level assembly code: "variables" don't actually exist in the executable. To let the quantity and size of these "variables" change between compilation runs greatly complicates this process, though it's not completely impossible (as you've discovered, with non-standard variable-length arrays).

    Why can we only refer to memory on the heap through pointers, while memory on the stack can be referred to via a normal variable

    This is just a consequence of the syntax. C++'s "normal" variables happen to be those with automatic or static storage duration. The designers of the language could technically have made it so that you can write something like Thing t = new Thing and just use a t all day, but they did not; again, this would have been more difficult to implement. How do you distinguish between the different types of objects, then? Remember, your compiled executable has to remember to auto-destruct one kind and not the other.

    I'd love to go into the details of precisely why and why not these things are difficult, as I believe that's what you're after here. Unfortunately, my knowledge of assembly is too limited.


    Why can't we allocate dynamic memory (ie memory of size that is only known at runtime) on the stack?

    Technically, this is possible. But not approved by the C++ standard. Variable length arrays(VLA) allows you to create dynamic size constructs on stack memory. Most compilers allow this as compiler extension.

    example:

    int array[n];
    
    //where n is only known at run-time
    

    Why can we only refer to memory on the heap through pointers, while memory on the stack can be referred to via a normal variable? Ie Thing t; .

    We can. Whether you do it or not depends on implementation details of a particular task at hand.

    example:

    int i;
    int *ptr = &i;
    

    We can allocate variable length space dynamically on stack memory by using function _alloca. This function allocates memory from the program stack. It simply takes number of bytes to be allocated and return void* to the allocated space just as malloc call. This allocated memory will be freed automatically on function exit.

    So it need not to be freed explicitly. One has to keep in mind about allocation size here, as stack overflow exception may occur. Stack overflow exception handling can be used for such calls. In case of stack overflow exception one can use _resetstkoflw() to restore it back.

    So our new code with _alloca would be :

     int NewFunctionA()
     {
      char* pszLineBuffer = (char*) _alloca(1024*sizeof(char));
      …..
      // Program logic
       ….
     //no need to free szLineBuffer
     return 1;
    }
    
    链接地址: http://www.djcxy.com/p/79832.html

    上一篇: 如何限制堆大小?

    下一篇: 为什么我们不能在堆栈上分配动态内存?