Similar to malloc and calloc in good old C, does the developer need to manually manage memory allocation and destruction in C++, and if yes, does that exercise pertain just to the stack and/or the heap too? If this is already documented somewhere on cplusplus.com (and I have searched), thanks for any pointers!
Besides, you don't manually manage stack allocations in C either. Compiler does that for you. It is the heap allocations that you have to do manually in C.
C++ Standard Library has custom types (classes) that encapsulate their own memory management. You usually create such objects (for example, a std::string) as automatic (local) variables (which compiler automanages in stack). The objects in turn automanage (heap) memory for the actual data that they store.
If you for some reason you do need some memory, then you'd use managed pointers (unique_ptr, shared_ptr etc). See http://www.cplusplus.com/reference/memory/ (Note don't use auto_ptr which is still valid with some compilers).
Memory management in C++ is much less error-prone with the C++ standard library. C++ has containers (including std::string), dynamic and static sized, and smart pointers that relieve the programmer of the sordid and messy details of dealing with manual memory management.
Just like in C, C++ manages the stack and CPU registers too. I mention CPU registers because local variables can be stored there too.
C++ lets you do your own heap memory management, but that's a notoriously bug prone area of programming, so the standard library provides lots template classes for many of the structures that use dynamic memory. These template classes manage their own memory for you.
The standard library also provides low level templates to manage pointers to the heap (unique_ptr and shared_ptr). These handle much of the drudgery of managing memory on your own.
the c++ containers can be used in place of new and delete if you want to do something like a specialized tree container (have to write it yourself). Something like push back on a vector can replace 'new', and to delete, the data dies with the container and you can recycle 'deleted' positions (instead of calling push back, if you have empty slots, use those first) or you can reduce and trim it with vector management functions if needed. You can cheat a bit doing it this way too; eg to iterate every item you can use the hidden container instead of your pointer cloud (and the pointers can just be array index, or pointers, both work). Its a win-win if you do it carefully the slight performance loss can me minimized to near zero.