I'm reading Effective C++ 3rd Edition, item52 "Write placement delete if you write placement new".
I want to how to make the operator delete automatically called after construction throwing an exception.
#include <iostream>
using namespace std;
class A {
int i;
public:
static void* operator new(std::size_t size) throw(std::bad_alloc) {
return malloc(size);
}
static void operator delete(void* p) throw() {
cout << "delete" << endl;
free(p);
}
A() {
throw exception();
}
};
int main() {
A* a = new A;
}
The above codes only output:
terminate called after throwing an instance of 'std::exception'
what(): std::exception
[1] 28476 abort ./test_clion
Reference: operator delete, operator delete[]
I should write new in try {}. Know too little about exceptions for now.
#include <iostream>
using namespace std;
class A {
int i;
public:
static void* operator new(std::size_t size) throw(std::bad_alloc) {
return malloc(size);
}
static void operator delete(void* p) throw() {
cout << "delete" << endl;
free(p);
}
A() {
throw exception();
}
};
int main() {
try {
A* a = new A;
} catch (const exception&) {
}
}
And the output:
delete
Related
I have a simple program where I am trying to do operator overloading for new and delete.
Just for trying, I did operator overloading for new and delete in global scope apart from class scope.
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
void * operator new(size_t size)
{
cout<<"\n\nGlobal scope new:\n";
void * ptr = malloc(size);
return ptr;
}
void operator delete(void *ptr)
{
cout<<"\n\nGlobal scope delete:\n";
free(ptr);
}
class test
{
public:
int age;
string name;
test(string str, int a)
{
age = a;
name = str;
}
void display();
};
void test::display()
{
cout<<"\n\nname is:-"<<name<<" and age is :- "<<age<<endl;
}
int main()
{
test *t = new test("sanjeev",29);
if(t!=NULL)
cout<<"\n\nMemory allocated:"<<endl;
t->display();
delete t;
}
Now on executing this program I am seeing that new is called 3 times and delete is called 3 times.
If I declare new and delete operator overloading inside class only one time call to new and delete is happening.
What is the reason behind this flow?
std::string ultimately uses the global operator new. You're creating two std::strings.
You should override operator new in your base class if you don't want new to be called multiple times in this case:
class CBaseTest
{
public:
void *operator new(const size_t allocation_size)
{
cout<<"\n\nMy new invoked:\n";
return ::malloc(allocation_size);
}
void operator delete(void *block_of_memory)
{
cout<<"\n\nMy delete invoked:\n";
::free(block_of_memory);
}
};
class test : public CBaseTest
{
public:
int age;
string name;
test(string str, int a)
{
age = a;
name = str;
}
void display();
};
void test::display()
{
cout << "\n\nname is:-" << name << " and age is :- " << age << endl;
}
Here
test *t = new test("sanjeev", 29);
will invoke your new method.
Similarly,
delete t;
will invoke your delete method
Now, if you try to allocate memory using new for your class test or any classes derived from CBaseTest then your new will be called.
I search a method to overload operator of delete[] or suitable destructor for a code:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string name;
public:
A(string name){
this->name=name;
};
~A(){
cout<<"Destructor. Destroyed "<<name<<"\n";
};
void operator delete(void* p, A* a){
cout<<"-Delete "<<a->name<<"\n";
};
void operator delete(void* pointer){
cout<<"Delete"<<"\n";
};
void operator delete[](void* pointer){
cout<<"Delete[]"<<"\n";
};
};
int main(){
int number = 5;
A** a = new A* [ number ];
delete [] a;
system("pause");
return 0;
};
But whatever I tried default delete[] is started each time from the file delete2.cpp. What do I do wrong?
[ADDED] Added an attempt to overload delete[].
Your code is not creating or destroy instances of A, only pointers to it.
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string name;
public:
A() {}
A(string name){
this->name=name;
};
~A(){
cout<<"Destructor. Destroyed "<<name<<"\n";
};
void operator delete(void* p, A* a){
cout<<"-Delete "<<a->name<<"\n";
};
void operator delete(void* pointer){
cout<<"Delete"<<"\n";
};
void operator delete[](void* pointer){
cout<<"Delete[]"<<"\n";
};
};
int main(){
int number = 5;
A* a = new A[ number ];
delete [] a;
system("pause");
return 0;
};
Calls operator[] as expected: http://ideone.com/EuS3Hi
I have a class X and method addX() which allocates objects of X on the heap. I want to restrict client-code from directly allocating objects of X (so that the X *ptr = new X is not allowed).
I've declared new, new[] operators private, but since I'm allocating X's objects through addX() I need to define them (operators). So, what's their definition should look like?
Hide the constructors, use a factory function:
class A
{
public:
static A* create() { return new A; }
static void destroy(A* a) { delete a; }
protected:
A() {}
A(const A&) {}
A& operator=(const A&) {}
};
This is pretty easy.
#include <iostream>
#include <new>
class X {
public:
static void addX()
{
X* p1 = new X;
delete p1;
}
private:
void* operator new(std::size_t sz)
{
std::cout << "custom new for size " << sz << '\n';
return ::operator new(sz);
}
void* operator new[](std::size_t sz)
{
return ::operator new(sz);
}
};
int main()
{
X::addX();
}
Please have a look at the code below. Is this a smart pointer?
If so, why the first object, p1, is dangling at the end of the code? (That is p2 is deleted by the destructor but p1 remains, why?)
#include <iostream>
#include <vector>
using namespace std;
template <class T> class my_auto_ptr {
T* myptr;
public:
my_auto_ptr(T* ptr = 0) : myptr(ptr) { }
~my_auto_ptr() {
delete myptr;
}
T* operator ->() const {
if (myptr != nullptr) return myptr;
else throw runtime_error("");
}
T& operator* () const {
if (myptr != nullptr) return *myptr;
else throw runtime_error("");
}
T* release() {
T* rptr = myptr;
myptr = 0;
return rptr;
}
};
//----------------------------------
int main() try {
my_auto_ptr<vector<int> > p1(new vector<int>(4, 5));
cout << p1->size() << endl;
my_auto_ptr<int> p2(new int(6));
cout << *p2 << endl;
return 0;
}
//-------------------------------
catch (...) {
cerr << "Exception occurred.\n";
return 1;
}
Is this a smart pointer?
No. It is copyable and assignable, but performing either of those operations will result in multiple deletes. You need to make sure that it is either non-copyable and non-assignable, or that it implements the rule of 3 or 5.
I'm trying to make something like this work:
struct holder {
std::function<void()> destroyer;
template<typename T>
holder(T) = delete;
template<typename T>
holder(std::enable_if< WAS CREATED WITH new > pointer) {
destroyer = [=] { delete pointer; };
};
template<typename T>
holder(std::enable_if< WAS CREATED WITH new[] > array) {
destroyer = [=] { delete[] array; };
};
virtual ~holder() {
destroyer();
};
};
In a way that I could then simply make return new test; and return = new test[10]; on a function that would return holder. But I found out that it won't ever be treated as an array, as operator new[] returns a pointer.
Is there any way to achieve the desired result?
Thanks! :)
It is impossible; whether or not new or new[] was used is not part of the pointer's type information.
The only way I know of is through placement-new:
#include <new>
#include <iostream>
struct A
{
void* operator new(std::size_t n, void* ptr)
{
std::cout << "operator new()\n";
return ptr;
}
void* operator new[](std::size_t n, void* ptr)
{
std::cout << "operator new[]\n";
return ptr;
}
};
int main()
{
A* ptr;
new (ptr) A();
new (ptr) A[5];
}