I need singleton with a application lifetime, guaranteed creation/destruction and static access to it.
#include <iostream>
#include <cstdlib>
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#define M() C::sM()
#define M2() C::sM2()
using namespace std;
class C {
private:
static C* s;
~C() { cout << "~C()" << endl; }
static C* instance() {
if (s==NULL) { s=new C(); }
cout << "instance()=" << s << endl; return s;
}
static void cleanUp() { delete s; }
void m() { cout << "m()" << endl; }
void m2() { cout << "m2()" << endl; }
DISALLOW_COPY_AND_ASSIGN(C);
public:
C() {
cout << "C()" << endl; if (s==NULL) {
s=this; atexit(&cleanUp);
cout << "cleanUp is installed" << endl;
} else {
cout << "cleanUp is not installed" << endl;
}
}
void* operator new(size_t sz) {
void* p=NULL; if (s==NULL) { p=new char[sz]; } else { p=s; }
cout << "new(" << sz << ")=" << p << endl;
return p;
}
void operator delete(void* p, size_t sz) {
cout << "delete(" << sz << "," << p << ")" << endl;
if (p) delete[] static_cast<char*>(p); s=NULL;
}
void static sM() { cout << "sM()" << endl; instance()->m(); }
void static sM2() { cout << "sM2()" << endl; instance()->m2(); }
};
C* C::s = NULL;
int main() {
M();
M2();
C* p1 = new C();
C* p2 = new C();
}
But I don't know how to get rid of g++ warning:
test.cpp: In static member function 'static void C::operator delete(void*, size_t)':
test.cpp:22: warning: deleting 'void*' is undefined
If I write C* instead of void*, destructor start calling itself in infinite loop. Can anybody help me to get clean code without warnings? C++98 of course.
The way I'm used to write singletons (whenever I really need one) is:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
private:
Singleton()
{
}
};
No need to mess around with overloading new and delete.
You do not need to overload neither new() nor delete().
And you probably do not need to hand out a pointer to your customers. A reference will do.
Construction and destruction of the singleton will be done in your instance(), which could look like so:
static C& instance() {
static C _instance;
cout << "instance()" << endl;
return _instance;
}
This guarantees construction and destruction, because the constructor of C is called when the first user calls instance(), and only with the first call.
Destruction will happen at the end of your program.
The type to delete is char*:
void operator delete(void* p, size_t sz) {
cout << "delete(" << sz << "," << p << ")" << endl;
if (p) delete (char*) p;
}
There is a bug in your new: What's the difference between new char[10] and new char(10)
Maybe should be:
p=new char[sz];
and then
delete[] (char*)p ;
---- edited:
The delete for purists, sacrificing clarity to people learning ;P :
delete[] static_cast<char*>(p) ;
(*actually I appreciate the note about the cast)
It looks to me like your code should work if you just remove the new and delete overloads (which I don't really see the point of, if you want to log every con/destruction, do so in the con/destructors), but the below should fix your error.
Since you assign a char* to p, casting it to char* in the delete should work, i.e. delete (char*)p;.
However, I believe p=new char(sz); is making a char with a value of sz instead of a char array of size sz. For the latter, you may want p=new char[sz]; and then delete[] p or delete[] (char*)p;.
Related
I found a problem while using 3rd party code which cannot be altered. I need to make a copy of object member. I can't do this strictly because one of inner members has private assignment operator. The only solution I found is tricky so I want to ask you if you see any red lights that can affect my program.
Here's the simplified code I'm dealing with (remember that I cannot change it!):
#include <iostream>
#include <algorithm>
class MBool
{
public:
MBool() {};
MBool(const MBool& arg) {}
private:
MBool& operator=(const MBool& arg);
};
class InnerContent {
private:
int* pBuffer;
public:
InnerContent() {
pBuffer = new int[20];
std::cout << "InnerContent()" << std::endl;
}
InnerContent(const InnerContent& otherInnerContent) {
pBuffer = new int[20];
std::copy(otherInnerContent.pBuffer, otherInnerContent.pBuffer + 20, pBuffer);
std::cout << "InnerContent(const InnerContent&)" << std::endl;
}
~InnerContent() {
std::cout << "~InnerContent()" << std::endl;
delete [] pBuffer;
pBuffer = nullptr;
}
virtual void someVirtualFunction() {}
};
class Content {
public:
InnerContent innerContent;
int someNumber;
MBool boolVar;
Content() {
std::cout << "Content()" << std::endl;
}
~Content() {
std::cout << "~Content()" << std::endl;
}
Content(const Content& otherContent) :
innerContent(otherContent.innerContent),
someNumber(otherContent.someNumber),
boolVar(otherContent.boolVar)
{
std::cout << "Content(const Content&)" << std::endl;
}
virtual void someVirtualFunction() {}
};
class A {
public:
Content content;
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
class B {
public:
Content content;
B() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
};
And here's what I'm about to do with it (only this code can be modified and extended):
void copyContent(Content& contentFrom, Content& contentTo) {
contentTo.~Content();
new (&contentTo) Content(contentFrom);
};
int main() {
A a;
B b;
// I wish to do this:
//b.content = a.content;
// but Content class has no operator= function implemented
// also I can't use generated assignment operator function because of MBool::operator= is private
// The only work-around I found is this:
std::cout << "--- Before copying" << std::endl;
copyContent(a.content, b.content);
std::cout << "--- After copying" << std::endl;
}
My solution is to call Content destructor manually to free any dynamically allocated memory in Content and its inner classes. Memory on the stack remains untouched so I can reuse it with placement-new operator that calls copy constructor that is present and does exactly what I need. When main function scope ends 'a' object is cleaned up properly.
Code output:
InnerContent()
Content()
A()
InnerContent()
Content()
B()
--- Before copying
~Content()
~InnerContent()
InnerContent(const InnerContent&)
Content(const Content&)
--- After copying
~B()
~Content()
~InnerContent()
~A()
~Content()
~InnerContent()
I don't want to make my own function that copies all the fields because this class can be updated in new version and there may be additional field that I will not copy and most probably no one will remember to fix it.
Question: Do you think this may cause any memory leaks or memory corruption? Do you see any problems that I didn't mention?
Basically the Idea should work. To protect yourself from forgetting to call the destructor, I think, you should wrap the whole think in a kind of smart pointer like class template. In this example it actually does not wrap a pointer, but the content object itself.
template <typename ContentType>
class content_wrapper {
private:
ContentType content_;
public:
content_wrapper() : content_ {} {};
content_wrapper(const content_wrapper& other) :
content_{other.content_} {};
content_wrapper& operator = (const content_wrapper& other) {
content_.~ContentType();
new (&content_) ContentType(other);
return *this;
}
ContentWrapper& operator * () {
return content_;
}
ContentWrapper* operator -> () {
return &content_;
}
};
now you can use it like that:
class A {
public:
content_wrapper<Content> content;
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
class B {
public:
content_wrapper<Content> content;
B() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
};
int main() {
A a;
B b;
b.content = a.content; // the wrapper will take care.
b.content->someVirtualFunction();
}
Easy to read and you can never forget the destructor call, whenever you want to assign a content object.
I have read this link about new and delete in C++. There is a code that implemented Singleton pattern. I have tested this code:
#include <iostream>
#include <memory>
class Singleton {
static Singleton *instance;
static std::size_t refcount;
std::string _s;
public:
void setS(std::string s) { _s = s; }
std::string getS() { return _s; }
static void *operator new(std::size_t nbytes) throw (std::bad_alloc) {
std::cout << "operator new" << std::endl;
if (instance == nullptr) {
std::cout << "operator new nullptr" << std::endl;
instance = ::new Singleton; // Use the default allocator
}
refcount++;
return instance;
}
static void operator delete(void *p) {
std::cout << "operator delete" << std::endl;
if (--refcount == 0) {
std::cout << "operator delete" << refcount << std::endl;
::delete instance;
instance = nullptr;
}
}
};
Singleton *Singleton::instance = nullptr;
std::size_t Singleton::refcount = 0;
int main() {
Singleton* s = new Singleton;
//Singleton* t = new Singleton;
s->setS("string s");
std::cout << "s " << s->getS() << std::endl;
Singleton* t = new Singleton;
std::cout << "t " << t->getS() << std::endl;
return 0;
}
But the result is:
operator new
operator new nullptr
s string s
operator new
t
Why t didn't print out "string s"? If I change the comment line, t can print out "string s".
The statement new Singleton will call operator new to aquire storage, and then intialize the non-static members of the object using the default constructor.
As _s is not static, it will be (re)initialized every time a new Singleton is created. So will result in a blank string for t.
It is very likely UB to reuse the space for the _s member this way.
Someone knows why the Latter syntax for calling , Dog::operator new is calling the default constructor after doing the allocation, ending up calling 2 constructors ?
I want to know if I'm doing something wrong, and how can I do:
Dog *ptr = new("arg") Dog();
without calling 2 constructors. and without using any trick, like checking in the default constructor if the object is already constructed. Here is the code:
class Dog
{
public:
Dog() // default
{
std::cout << "default Dog constructor [" << this << "]" << std::endl;
}
Dog(int x) // int argument
{
std::cout << "dog constructor int " << x << "[" << this << "]" << std::endl;
}
Dog(const std::string& word) // std::string argument
{
std::cout << "dog constructor std::string: " << word << " ["<< this << "]" << std::endl;
}
Dog(std::string &&word) // rvalue string argument
{
std::cout << "dog constructor std::string&& rvalue: " << word << " [" << this << "]" << std::endl;
}
// custom operator new
static void *operator new(std::size_t size) noexcept // for default constructor
{
Dog *ptr = (Dog*)malloc(size); // allocate memory
if (ptr) // if allocate ok
{
::new(ptr) Dog(); // call default constructor on object in memory
return ptr; // returns
}
else
return nullptr;
}
template<class T>
static void * operator new(std::size_t size, T&& value) noexcept // for argument constructor
{
Dog *ptr = (Dog*) malloc(size); // allocate the memory
if (ptr)
{
::new (ptr) Dog(std::forward<T>(value)); // pass the argument exactly as was passed to operator new,
// using perfect forwarding
return ptr;
}
else
return nullptr;
}
~Dog() { std::cout << "destructor " << std::endl; }
};
int main(void)
{
Dog *d = (Dog*) Dog::operator new(sizeof(Dog), "Const Char * Argument"); // argument version
Dog *d2 = (Dog*)Dog::operator new(sizeof(Dog)); // default constructor argument
//1 this works as expected, do what you specified in the member operator new, everything goes normal.
Dog *d3 = new Dog(); // default constructor
Dog *d4 = new("Const Char * Argument") Dog(); // argument constructor
// this is shorter, goes into your member operator new, BUT when it returns to this scope,
// call the default constructor for *d3, and for *d4 too.
// so this ends up calling constructors twice for both objects.
}
So, I was mixing allocation with construction, there's no reason for doing that here, maybe there is some use for that in operator new[] to construct the array with a contructor other than the default contructor.
But the the best way to define these members operators are:
class Dog {
public:
// .......
// custom operator new
static void *operator new(std::size_t size) noexcept // for default constructor
{
void *memory = malloc(size); // allocate memory
if (memory) // if allocate ok
{
return memory; // returns
}
else
return nullptr;
}
static void *operator new[](std::size_t size) noexcept
{
void *memory = malloc(size); // allocate memory
if (memory) // if allocate ok
{
return memory; // returns
}
else
return nullptr;
}
static void operator delete(void *block) noexcept
{
free(block);
}
static void operator delete[](void *block) noexcept
{
free(block);
}
~Dog() { std::cout << "destructor " << std::endl; }
};
int main(void)
{
// now we can use new operator normaly without complications
Dog *d1 = new Dog[10]; // default constructor on all objects
Dog *d2 = new Dog("const char * argument"); // call std::string&& constructor
delete[] d1;
delete d2;
}
Using (keyword) new: It invokes the allocating operator new and (!) calls the constructor.
Note: When providing an operator new you should provide an operator delete, too (in your case it would call free). Also, do not forget the array versions.
I was wondering if it was possible to return specific implementations of an interface without using an abstract factory, so I put a simple use case.
Now, aside from being a little unorthodox, the test case produces the expected output.
allocating implementation
interface ctor
implementation ctor
5
implementation dtor
interface dtor
freeing implementation
However, I have never seen anyone do things this way before, so I was wondering if there was anything fundamentally wrong with this approach.
edit: The purpose of this is to hide platform specific code from the caller without using the abstract factory or pimpl design patterns.
MyInterface.h
class MyInterface
{
public:
MyInterface();
MyInterface(int);
virtual ~MyInterface();
void *operator new(size_t sz);
void operator delete(void *ptr);
virtual int GetNumber(){ return 0; }
};
MyImplementation.cpp
#include "MyInterface.h"
class MyImplementation : public MyInterface
{
int someData;
public:
MyImplementation() : MyInterface(0)
{
cout << "implementation ctor" << endl;
someData = 5;
}
virtual ~MyImplementation()
{
cout << "implementation dtor" << endl;
}
void *operator new(size_t, void *ptr)
{
return ptr;
}
void operator delete(void*, void*){}
void operator delete(void *ptr)
{
cout << "freeing implementation" << endl;
free(ptr);
}
virtual int GetNumber() { return someData; }
};
/////////////////////////
void* MyInterface::operator new(size_t sz)
{
cout << "allocating implementation" << endl;
return malloc(sizeof(MyImplementation));
}
void MyInterface::operator delete(void *ptr)
{
// won't be called
}
MyInterface::MyInterface()
{
new (this) MyImplementation;
}
MyInterface::MyInterface(int)
{
cout << "interface ctor" << endl;
}
MyInterface::~MyInterface()
{
cout << "interface dtor" << endl;
}
Test.cpp
int main()
{
MyInterface *i = new MyInterface;
cout << i->GetNumber() << endl;
delete i;
return 0;
}
If you create a MyInterface on the stack this is obviously going to cause problems since there won't be enough memory at that location for the implementation.
Even if you always allocate it on the heap, it smells like undefined behavior since you re-construct over a half-constructed base class (one could argue this violates the "two distinct objects must have different addresses" clause).
Unfortunately I can't tell the real problem you're trying to solve so I cant' give you specific answer(s) about that.
When I override copy constructor why it segfaults in first delete itself.
output:
$./a.out
inside ctor
inside copy-ctor
Say i am in someFunc
inside dtor
*** glibc detected *** ./a.out: free(): invalid pointer: 0xb75f3000 ***
if I do not override copy-ctor then I could see that s1.PrintVal() is getting called and then there is seg fault in *ptr that is expected.
Why there is two different behavior with and without default and overridden copy-ctor?
#include<iostream>
using namespace std;
class Sample
{
public:
int *ptr;
Sample(int i)
{
cout << "inside ctor" << endl;
ptr = new int(i);
}
Sample(const Sample &rhs)
{
cout << "inside copy-ctor" << endl;
}
~Sample()
{
cout << "inside dtor" << endl;
delete ptr;
}
void PrintVal()
{
cout <<" inside PrintVal()."<<endl;
cout << "The value is " << *ptr<<endl;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
return 0;
}
In your copy-ctor, you don't actually copy ptr, meaning its value will be unspecified, and you'll be deleting an unspecified pointer (instead of double-deleting a normal pointer as you do with the defauly copy-ctor).
The default copy ctor copies every member by value. This will create an alias to the pointer so each class when its dtor is called will delete the pointer and cause a fault.
In almost any class where you have a pointer that is being allocate you will need to write a custom copy constructor to allocate the pointer and then copy the value.
class Sample
{
public:
int *ptr;
Sample(int i)
{
cout << "inside ctor" << endl;
ptr = new int(i);
}
Sample(const Sample &rhs)
{
ptr = new int(*rhs.ptr);
}
Sample & operator=(const Sample& other)
{
// You should also override copy assignment if you overide copy
// you don't need to allocate in this case just copy the value
*ptr = *other.ptr;
}
~Sample()
{
cout << "inside dtor" << endl;
delete ptr;
}
void PrintVal()
{
cout <<" inside PrintVal()."<<endl;
cout << "The value is " << *ptr<<endl;
}
};
You should look up the rule of three and if your in c++ 11 the rule of five