#include <iostream>
#include <memory>
#include <vector>
struct Yoo
{
Yoo(const char* s) : str(new std::string(s)) {}
~Yoo() { delete str; str = nullptr; }
std::string* str;
};
const size_t K = 1024;
const size_t SZ = 16 * K; // some big size
struct YooDeleter
{
void operator()(Yoo* p) { delete p; }
char dummy[SZ]; // make the deleter big
};
void bar()
{
std::shared_ptr<Yoo> sp;
Yoo* p = new Yoo("Hello");
// try to exhaust heap memory.
std::vector<std::unique_ptr<YooDeleter>> holder;
holder.reserve(2048 * K); // 2M entries, big enough
for (;;)
{
try
{
std::unique_ptr<YooDeleter> p(new YooDeleter);
holder.push_back(std::move(p));
}
catch (...)
{
break;
}
}
std::cout << "Heap used: " << holder.size() << " x " << SZ / K << "KB" << std::endl;
try
{
YooDeleter x;
std::cout << "Creating shared_ptr..." << std::endl;
sp = std::shared_ptr<Yoo>(p, x);
}
catch (std::bad_alloc& e)
{
// cannot construct sp: out of memory
std::cout << "Out of memory..." << std::endl;
std::cout << "I am about to crash..." << std::endl;
std::cout << p->str->c_str() << std::endl; // undefined behavior, mostly crash
delete p; // will not even arriving here!
return;
}
catch(...)
{
std::cout << "Unknown error..." << std::endl;
return;
}
// it will never be here!
*sp->str = "Bye";
std::cout << sp->str->c_str() << std::endl; // "Bye"
}
int main()
{
bar();
return 0;
}