Reputation: 1132
I am new to C++ and thus new to smart pointers concept and usage as well. I want to allocate memory dynamically for a struct in a function and then once the receiver is done using that memory. I want the unique (not shared) receiver to safely release the memory. Something like the following:
typedef struct {
int x;
int y;
} myStruct;
myStruct* initMem(void)
{
myStruct* result = new myStruct();
result->x = 12;
result->y = 14;
return result;
}
int main()
{
cout << ">>>>> Main | STARTED <<<<<" << endl;
myStruct* w = initMem();
cout << w->x << endl;
cout << w->y << endl;
delete w;
return 1;
}
Note: Above is just a sample example of what I want to achieve. The structs are far more complicated than that and I have to use dynamic memory allocations only.
I read that playing with raw pointers in C++ for dynamic memory management is not good as C++ has the concept of smart pointers especially for this. Can you please help me in converting the above logic to using smart pointers.
Thanks in advance.
Upvotes: 0
Views: 534
Reputation: 3186
Use a unique pointer std::unique_ptr
. If coding with c++14 and later, then you can benefit from the std::make_unique
which creates a myStruct
object and wraps it around a unique pointer.
But even if you don't use c++14 or later, then you can simply create the make_unique
function yourself and use it accordingly.
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
So the following example in c++11 would use make_unique
instead of std::make_unique
.
#include <iostream>
#include <memory>
struct myStruct
{
int x;
int y;
myStruct(int x_, int y_) : x(x_), y(y_)
{
std::cout<< "Calling user-def constructor..." <<std::endl;
}
~myStruct()
{
std::cout<< "Calling default destructor..." <<std::endl;
}
};
int main()
{
std::cout << ">>>>> Main | STARTED <<<<<" << std::endl;
std::unique_ptr<myStruct> ptr = std::make_unique<myStruct>(2,3);
std::cout<< ptr->x << "," << ptr->y <<std::endl;
}
Example online: https://rextester.com/TLIPO27824
Upvotes: 1
Reputation: 75853
There is no reason to use pointers and dynamically allocated memory. Use automatic storage duration:
myStruct initMem()
{
myStruct result{};
result.x = 12;
result.y = 14;
return result;
}
int main()
{
cout << ">>>>> Main | STARTED <<<<<" << endl;
myStruct w = initMem();
cout << w.x << endl;
cout << w.y << endl;
}
If you have a good reason for using dynamically allocated memory then you must adhere to the RAII principle. Smart pointers in the standard library do just that:
std::unique_ptr<myStruct> initMem(void)
{
auto result = std::make_unique<myStruct>();
result->x = 12;
result->y = 14;
return result;
}
int main()
{
std::cout << ">>>>> Main | STARTED <<<<<" << std::endl;
std::unique_ptr<myStruct> w = initMem();
std::cout << w->x << std::endl;
std::cout << w->y << std::endl;
}
Also in C++ you don't need the typedef. Actually it is idiomatic to not use it:
struct myStruct {
int x;
int y;
};
Upvotes: 1