How to deallocate variables on the stack?

前端 未结 6 1705
一向
一向 2021-01-29 14:15

Is there a way to deallocate variables and/or objects created on the stack? I am specifically talking about the stack not the heap.

I do not want to debate whether this

相关标签:
6条回答
  • 2021-01-29 14:57
    {
      int a;
    } // 'a' "deallocated" here
    

    You can't get rid of a before the end of the enclosing scope.

    0 讨论(0)
  • 2021-01-29 15:03

    Every time you return from a function, any memory allocated on the stack by that function is deallocated. If you need to reduce the scope of a variable for some reason, you can just make a new smaller scope by creating a block with {}.

    void function(void)
    {
       int x;
       {
         int y;
       } // scope of y ends
    } // scope of x ends
    
    0 讨论(0)
  • 2021-01-29 15:03

    Stack variables are deallocated when they go out of scope. That's it.

    0 讨论(0)
  • 2021-01-29 15:05

    No, it's not possible to deallocate a stack variable before it goes out of scope in portable C++.

    It would be possible to do something retarded and non-portable with inline assembly like this (example works only with x86, only with Visual Studio):

    int* ptr;
    
    __asm {
        sub esp, sizeof(int)           // allocate variable
        mov [esp + sizeof(int)], esp   // move its address into ptr
    }
    
    *ptr = 4;                          // assign 4 to the variable
    cout << *ptr << endl;              // print variable
    
    __asm {
        add esp, sizeof(int)           // deallocate variable
    }
    

    But don't, there are too many problems to name.

    0 讨论(0)
  • 2021-01-29 15:19

    You cannot prematurely end the lifetime of an "automatic" object, but you can end the lifetime of a dynamic object at any time. A dynamic object can be created on the stack just like an automatic variable, but it's a hair trickier.

    #include <new>
    #include <string>
    int main() {
        typedef std::aligned_storage<sizeof(std::string)> stringbuffer;
        stringbuffer buff;
        std::string& str =*new(buff)std::string("banana"); //str alive on stack
        std::cout << str;       
        str.~std::string(); // str is destroyed. DO NOT FORGET
        std::cout << '\n';
    }
    

    This is error prone, so of course, boost has code for this.

    int main() {
        boost::optional<std::string> str;
        str = "banana"; //str is alive on the stack
        std::cout << str;       
        str = boost::none; //str is destroyed.  Ok to forget
        std::cout << '\n';
    }
    

    Both of these avoid the potential UB of FredOverflow's answer, since if an exception is thrown while the object is not alive, the destructor is not automatically called on the dead object.

    Azza notes that this does not deallocate the space, it merely destructs. It is impossible to deallocate the space early.

    0 讨论(0)
  • 2021-01-29 15:22

    The question is meaningless. Generally, stack for thread is allocated (memory reserved and partially committed) on process heap when thread is created. And dealocated when thread (normally) exits . It has a fixed maximum size (reserved memory) during run-time and "grows" by committing more memory from reserved pool. There is no actual memory allocation happens when function call uses stack - the stack space function uses (for its local variables) is a region of pre-allocated and committed memory. You cannot de-allocate it.

    Imagine, you allocated 100 bytes on heap at address addr, pass pointer to addr+0x40 and size 0x10 to function for it to use internally. Function can create some variables (objects) at this address, total size no more than 16 bytes, using, say, placement new. It can (and, generally, should) destroy objects by calling destructors explicitly. But it has no business deallocating any memory - pointer passed to it does not even point to the beginning of allocated region... And that's, very simplified, how stack works - function gets portion of pre-allocated memory for its local variables, it calls constructors at this memory, then upon exit it calls destructors. But it does not allocate or deallocate any stack space. Attempt to do it will cause access violation (segmentation fault).

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