Since C++11, the C++ standard library provides two types of smart pointer:
- Class shared_ptr for a pointer that implements the concept of shared ownership. Multiple
smart pointers can refer to the same object so that the object and its associated resources
get released whenever the last reference to it gets destroyed. To perform this task in more complicated
scenarios, helper classes, such as weak_ptr, bad_weak_ptr, and enable_shared_from_this,
are provided. - Class unique_ptr for a pointer that implements the concept of exclusive ownership or strict
ownership. This pointer ensures that only one smart pointer can refer to this object at a time.
However, you can transfer ownership. This pointer is especially useful for avoiding resource
leaks, such as missing calls of delete after or while an object gets created with new and an
exception occurred.
#include <string>
#include <fstream> // for ofstream
#include <memory> // for shared_ptr
#include <cstdio> // for remove()
class FileDeleter
{
private:
std::string filename;
public:
FileDeleter (const std::string& fn)
: filename(fn) {
}
void operator () (std::ofstream* fp) {
delete fp; // close file
std::remove(filename.c_str()); // delete file
}
};
int main()
{
// create and open temporary file:
std::shared_ptr<std::ofstream> fp(new std::ofstream("tmpfile.txt"), // call constructor
FileDeleter("tmpfile.txt"));
fp = nullptr; //call fp destructor
return 0;
//...
}
#include <memory> // for shared_ptr
#include <sys/mman.h> // for shared memory
#include <fcntl.h>
#include <unistd.h>
#include <cstring> // for strerror()
#include <cerrno> // for errno
#include <string>
#include <iostream>
class SharedMemoryDetacher
{
public:
void operator () (int* p) {
std::cout << "unlink /tmp1234" << std::endl;
if (shm_unlink("/tmp1234") != 0) {
std::cerr << "OOPS: shm_unlink() failed" << std::endl;
}
}
};
std::shared_ptr<int> getSharedIntMemory (int num)
{
void* mem;
int shmfd = shm_open("/tmp1234", O_CREAT|O_RDWR, S_IRWXU|S_IRWXG);
if (shmfd < 0) {
throw std::string(strerror(errno));
}
if (ftruncate(shmfd, num*sizeof(int)) == -1) {
throw std::string(strerror(errno));
}
mem = mmap(nullptr, num*sizeof(int), PROT_READ | PROT_WRITE,
MAP_SHARED, shmfd, 0);
if (mem == MAP_FAILED) {
throw std::string(strerror(errno));
}
return std::shared_ptr<int>(static_cast<int*>(mem),
SharedMemoryDetacher());
}
int main()
{
// get and attach shared memory for 100 ints:
std::shared_ptr<int> smp(getSharedIntMemory(100));
// init the shared memory
for (int i=0; i<100; ++i) {
/*shared_ptrs provide only operators * and ->. Pointer arithmetic and operator [ ] are
not provided. Thus, to access the memory, you have to use get()*/
smp.get()[i] = i*42;
}
// deal with shared memory somewhere else:
//...
std::cout << "<return>" << std::endl;
std::cin.get();
// release shared memory here:
smp.reset();
//...
}