Write a code related to memory management and garbage collection and find it's efficiency and complexity. (in dev-c++/Data structures) (Please provide proper explanation of code's efficiency and complexity for beginner)
Solution
Code related to memory management
Memory in your C++ program is divided into two parts − The stack − All variables declared inside the function will take up memory from the stack. The heap − This is unused memory of the program and can be used to allocate the memory dynamically when program runs. C++ allows us to allocate the memory of a variable or an array in run time. This is known as dynamic memory allocation.
We can allocate and then deallocate memory dynamically using the new and delete operators respectively.
New operator
The new operator allocates memory to a variable. For example code ,
// declare an int pointer
int* pointVar;
// dynamically allocate memory
// using the new keyword
pointVar = new int;
// assign value to allocated memory
*pointVar = 45;
Delete Operator
Once we no longer need to use a variable that we have declared dynamically, we can deallocate the memory occupied by the variable.
For this, the delete operator is used. It returns the memory to the operating system. This is known as memory deallocation.
The syntax for this operator is
delete pointerVariable;
Consider the code:
// declare an int pointer
int* pointVar;
// dynamically allocate memory
// for an int variable
pointVar = new int;
// assign value to the variable memory
*pointVar = 45;
// print the value stored in memory
cout << *pointVar; // Output: 45
// deallocate the memory
delete pointVar;
Here, we have dynamically allocated memory for an int variable using the pointer pointVar.
C++ Dynamic Memory Allocation Example
#include <iostream>
using namespace std;
int main() {
// declare an int pointer
int* pointInt;
// declare a float pointer
float* pointFloat;
// dynamically allocate memory
pointInt = new int;
pointFloat = new float;
// assigning value to the memory
*pointInt = 45;
*pointFloat = 45.45f;
cout << *pointInt << endl;
cout << *pointFloat << endl;
// deallocate the memory
delete pointInt, pointFloat;
return 0;
}
Output
45
45.45
Code related to garbage collection
Garbage collection is a form of automatic memory management. The garbage collector attempts to reclaim garbage, or memory used by objects that will never be accessed or mutated again by the application. One of more widely used libraries that provides this function is Hans Boehm's conservative GC.
C++ is old fashioned. C++ has no garbage collection. At first, garbage collection breaks one of the key principles of C++: "Don't pay for something you don't use." That means, if you don't need garbage collection your C++ runtime should not waste its time cleaning up the whole garbage. My second point is more sophisticated. We have RAII in C++ and therefore the totally deterministic destruction of objects. RAII stand for Resource Acquisition Is Initialization. Probably, the most important idiom in C++ says that a resource should be acquired in the constructor of the object and released in the destructor of the object. The key is that the destructor will be automatically called if the object goes out of scope.
The example shows the totally deterministic behaviour of RAII in C++.
#include <iostream>
#include <new>
#include <string>
class ResourceGuard{
private:
const std::string resource;
public:
ResourceGuard(const std::string& res):resource(res){
std::cout << "Acquire the " << resource << "." << std::endl;
}
~ResourceGuard(){
std::cout << "Release the "<< resource << "." << std::endl;
}
};
int main(){
std::cout << std::endl;
ResourceGuard resGuard1{"memoryBlock1"};
std::cout << "\nBefore local scope" << std::endl;
{
ResourceGuard resGuard2{"memoryBlock2"};
}
std::cout << "After local scope" << std::endl;
std::cout << std::endl;
std::cout << "\nBefore try-catch block" << std::endl;
try{
ResourceGuard resGuard3{"memoryBlock3"};
throw std::bad_alloc();
}
catch (std::bad_alloc& e){
std::cout << e.what();
}
std::cout << "\nAfter try-catch block" << std::endl;
std::cout << std::endl;
}