-2

In C++, does RAII imply that a stack object (an object allocated on a stack, e.g. a local variable in a function) is deallocated only when execution gets out of the scope of the stack object?

What if I would like to deallocate a stack object a little bit before execution reaches the end of the scope of the stack object?

Thanks.

Tim
  • 1
  • 141
  • 372
  • 590
  • 1
    You cannot deallocate stack memory without leaving the scope. Perhaps you meant "destroy an object still on the stack"? – François Andrieux Sep 14 '17 at 20:49
  • 8
    Wouldn't creating a smaller scope inside your function and declaring your stack object there solve this? – Á. Márton Sep 14 '17 at 20:50
  • @FrançoisAndrieux Do "destroy an object still on the stack" and "deallocate stack memory without leaving the scope" mean the same? What is their difference? – Tim Sep 14 '17 at 20:52
  • @Á.Márton Then my question applies to the stack for the smaller scope. :) – Tim Sep 14 '17 at 20:53
  • 1
    @Tim Memory is allocated, objects are created. An object needs to be represented in memory, but you can have memory that does not represent an object. – François Andrieux Sep 14 '17 at 20:53
  • @FrançoisAndrieux Is what you described a memory leak for stack object? – Tim Sep 14 '17 at 20:53
  • 4
    @Tim No. You can't leak stack memory... It's conceptually impossible. – François Andrieux Sep 14 '17 at 20:54
  • @FrançoisAndrieux How do you "destroy an object still on the stack"? – Tim Sep 14 '17 at 20:54
  • 4
    You can't really do that in any reasonable way. But why would you want to? [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? – juanchopanza Sep 14 '17 at 20:55
  • 1
    @Tim I don't think its possible and I honestly can't think of any realistical situation where I would want this. The stack is the stack, it's supposed to be deallocated upon reaching the return address. – Á. Márton Sep 14 '17 at 20:56
  • 1
    @Tim You could call it's destructor explicitly (which would be a terrible idea). A more practical example would be to destroy an object created by placement new on aligned storage. The object was created on memory from the stack, then destroyed without that memory being deallocated right away. – François Andrieux Sep 14 '17 at 20:56
  • 1
    You can manually create and destroy object manually on stack memory using placement new, why would you need that? – Slava Sep 14 '17 at 20:56
  • @FrançoisAndrieux When calling a stack object's destructor explicitly, will the object be destroyed, and its memory be deallocated? – Tim Sep 14 '17 at 20:57
  • 4
    @Tim No. A destructor does not free the memory the object resided in. Second, if you explicitly destroy an object on the stack, it's destructor would be called again when leaving the scope, leading to undefined behavior. – François Andrieux Sep 14 '17 at 20:58
  • @FrançoisAndrieux Thanks. What is `placement new`? Is it different from `new`? – Tim Sep 14 '17 at 20:58
  • @Tim There are many answered questions on Stack Overflow about what placement new is. For example : https://stackoverflow.com/questions/35087204/how-c-placement-new-works Placement new creates a new object, except it doesn't allocate memory. Instead, you must provide a pointer to properly sized and aligned memory where that object will be created. – François Andrieux Sep 14 '17 at 20:59
  • @Tim start reading here: [for info on placement new](http://en.cppreference.com/w/cpp/language/new). – Jesper Juhl Sep 14 '17 at 21:01
  • The advantage of disposing of the object's resources in the destructor when the object goes out of scope is you know it'll be called if there's an exception. Whereas if you're desposing by calling some function method instead of the destructor this won't happen and you could find yourself leaking something. – Robinson Sep 14 '17 at 21:35
  • @FrançoisAndrieux I am wondering if "A destructor does not free the memory the object resided in" is correct. From https://en.wikipedia.org/wiki/Destructor_(computer_programming) "In object-oriented programming, a destructor (dtor) is a method which is automatically invoked when the object is destroyed. ... Its main purpose is to free the resources (**memory allocations**, open files or sockets, database connections, resource locks, etc.) which were acquired by the object during its life and/or deregister from other entities which may keep references to it. " – Tim Sep 14 '17 at 23:24
  • 1
    @Tim - This doesn't apply if you invoke the destructor "non-automatically". The standard way to get an object destroyed early is to put it in a smaller function and call that function. The object is destroyed when the function returns. – Bo Persson Sep 14 '17 at 23:31
  • @BoPersson By "This doesn't apply if you invoke the destructor non-automatically", do you mean that a destructor just does what is written inside its function body, and what is inside its function body may or might not have deallocation operation of the memory of the object? – Tim Sep 14 '17 at 23:36
  • 1
    *"a destructor (dtor) is a method which is automatically invoked when the object is destroyed."* is a one way street. It doesn't mean that the memory is released if the destructor is called. It means that the destructor is called before the memory is released. Either by leaving a scope or explicitly using `delete` for dynamic memory. – Bo Persson Sep 14 '17 at 23:53
  • @Bo Thanks. A destructor just does what is written inside its function body, correct? "explicitly using delete for dynamic memory" must be explicitly written in a descrutor's function body? – Tim Sep 14 '17 at 23:56
  • @Tim That passage refers to memory allocations preformed by the class constructor. That is, if a class allocated memory (distinct from the memory that is provided for itself) and it has not yet released it by the time the destructor is called, that memory (and any other resources still owned by the object) should be released at this point. The passage does *not* refer to the memory the object occupies. An example would be `std::vector`. It's destructor will destroy every object it contains and the memory it allocated to store those objects. – François Andrieux Sep 15 '17 at 13:20
  • @Tim Another thing `std::vector` illustrates well is the distinction between memory allocation and object creation. If you `pop_back` an element, it destroys the last object in the vector but does not release it's memory. Similarly, if you `push_back` and element, and if it's capacity is sufficient to accommodate another element, then an object is constructed but no additional memory is allocated. When you use `reserve` you allocate memory to be used later. Eventually, maybe, you will construct and destroy objects using that memory. Construction is distinct from allocation. – François Andrieux Sep 15 '17 at 13:22

1 Answers1

1

It sounds like you want std::optional. It allows automatic resource management, but also allows a "deallocated" state.

o11c
  • 15,265
  • 4
  • 50
  • 75