By "placed in a destructor", $l4xklynx, I think you referring to an object like a linked list, or other data structure which may dynamically allocate memory (for example, to add nodes) in addition to the memory occupied by the class object itself. For example, a List object itself may consist of only a pointer or two, and maybe some auxiliary variables holding information about the list (e.g., length). The List object contains no nodes, only pointers to nodes. When nodes are added to the list, generally the only pointers to those nodes are the pointers in the List object, or pointers in other nodes which belong to the list.
The default destructor for the List will release only the memory that belongs to the List object itself -- its own pointers and auxiliary variables. It does nothing about the memory that belongs to the nodes, and once the List's pointers are gone those nodes will be inaccessible and the memory they occupy remains unusable.
So in this situation, you explicitly write a destructor containing code to step through the list and delete each node one at a time.
But the point about "releasing the memory back to the operating system" vs. letting the memory be "reused by the objects" is less clear. Probably that book is trying to distinguish between objects allocated on the program's stack (this would be any objects created when the program is initally loaded), and objects allocated on the heap (dynamically allocated during runtime). If I'm not mistaken, the memory that was allocated on the stack would still belong to the program as long as the program continues to run, but memory that was allocated on the heap is returned to the operating system and can be reallocated by the OS to another process even while the first program is still running. Returning to the List example, if you write a destructor that steps through the list to delete its nodes, and your program contains a block of code which creates a List object:
Code:
... // other code
{List my_list;
my_list.add_node( ); // List::add_node() dynamically allocates memory to create a Node
... // bla bla bla
}
... // more code
at the end of that block {} your destructor for my_list will be called. It will delete the Node object and makes its memory available to the OS. The memory that was allocated to the List object my_list still belongs to the program and can't be reused by the OS while the program is still running, but since my_list goes out of scope at the end of the {} block, that memory is also no longer usable by the program.
Of course, I may be wrong. If so, someone please correct me.