How to prevent an object being created on the heap? - c++

Does anyone know how I can, in platform-independent C++ code prevent an object from being created on the heap? That is, for a class "Foo", I want to prevent users from doing this:
Foo *ptr = new Foo;
and only allow them to do this:
Foo myfooObject;
Does anyone have any ideas?
Cheers,

Nick's answer is a good starting point, but incomplete, as you actually need to overload:
private:
void* operator new(size_t); // standard new
void* operator new(size_t, void*); // placement new
void* operator new[](size_t); // array new
void* operator new[](size_t, void*); // placement array new
(Good coding practice would suggest you should also overload the delete and delete[] operators -- I would, but since they're not going to get called it isn't really necessary.)
Pauldoo is also correct that this doesn't survive aggregating on Foo, although it does survive inheriting from Foo. You could do some template meta-programming magic to HELP prevent this, but it would not be immune to "evil users" and thus is probably not worth the complication. Documentation of how it should be used, and code review to ensure it is used properly, are the only ~100% way.

You could overload new for Foo and make it private. This would mean that the compiler would moan... unless you're creating an instance of Foo on the heap from within Foo. To catch this case, you could simply not write Foo's new method and then the linker would moan about undefined symbols.
class Foo {
private:
void* operator new(size_t size);
};
PS. Yes, I know this can be circumvented easily. I'm really not recommending it - I think it's a bad idea - I was just answering the question! ;-)

I don't know how to do it reliably and in a portable way.. but..
If the object is on the stack then you might be able to assert within the constructor that the value of 'this' is always close to stack pointer. There's a good chance that the object will be on the stack if this is the case.
I believe that not all platforms implement their stacks in the same direction, so you might want to do a one-off test when the app starts to verify which way the stack grows.. Or do some fudge:
FooClass::FooClass() {
char dummy;
ptrdiff_t displacement = &dummy - reinterpret_cast<char*>(this);
if (displacement > 10000 || displacement < -10000) {
throw "Not on the stack - maybe..";
}
}

#Nick
This could be circumvented by creating a class that derives from or aggregates Foo. I think what I suggest (while not robust) would still work for derived and aggregating classes.
E.g:
struct MyStruct {
Foo m_foo;
};
MyStruct* p = new MyStruct();
Here I have created an instance of 'Foo' on the heap, bypassing Foo's hidden new operator.

Because debug headers can override the operator new signature, it is best to use the ... signatures as a complete remedy:
private:
void* operator new(size_t, ...) = delete;
void* operator new[](size_t, ...) = delete;

You could declare a function called "operator new" inside the Foo class which would block the access to the normal form of new.
Is this the kind of behaviour you want ?

You could declare it as an interface and control the implementation class more directly from your own code.

this can be prevented by making constructors private and providing a static member to create an object in the stack
Class Foo
{
private:
Foo();
Foo(Foo& );
public:
static Foo GenerateInstance() {
Foo a ; return a;
}
}
this will make creation of the object always in the stack.

Not sure if this offers any compile-time opportunities, but have you looked at overloading the 'new' operator for your class?

Related

Size of class instance

I'm working with a class for which the new operator has been made private, so that the only way to get an instance is to write
Foo foo = Foo()
Writing
Foo* foo = new Foo()
does not work.
But because I really want a pointer to it, I simulate that with the following :
Foo* foo = (Foo*)malloc(sizeof(Foo));
*foo = Foo();
so that can test whether the pointer is null to know whether is has already been initialized.
It looks like it works, from empirical tests, but is it possible that not enough space had been allocated by malloc ? Or that something else gets funny ?
--- edit ---
A didn't mention the context because I was not actually sure about why they the new operator was disabled. This class is part of a constraint programming library (gecode), and I thought it may be disabled in order to enforced the documented way of specifying a model.
I didn't know about the Concrete Data Type idiom, which looks like a more plausible reason.
That allocation scheme may be fine when specifying a standard model --- in which everything is specified as CDTs in the Space-derived class --- but in my case, these instance are each created by specific classes and then passed by reference to the constructor of the class that reprensents the model.
About the reason i'm not using the
Foo f;
Foo *pf = &f;
it would be like doing case 1 below, which throws a "returning reference to local variable" warning
int& f() { int a=5; return a; } // case 1
int& f() { int a=5; int* ap=&a; return *ap; }
int& f() { int* ap=(int*)malloc(sizeof(int)); *ap=5; return *ap; }
this warning disappears when adding a pointer in case 2, but I guess it is because the compiler loses tracks.
So the only option left is case 3 (not mentioning that additionaly, ap is a member of a class that will be initialized only once when f is called, will be null otherwise, and is the only function returning a reference to it. That way, I am sure that ap in this case when lose its meaning because of the compilier optimizing it away (may that happen ?)
But I guess this reaches far too much beyond the scope of the original question now...
Don't use malloc with C++ classes. malloc is different from new in the very important respect that new calls the class' constructor, but malloc does not.
You can get a pointer in a couple ways, but first ask yourself why? Are you trying to dynamically allocate the object? Are you trying to pass pointers around to other functions?
If you're passing pointers around, you may be better off passing references instead:
void DoSomething(Foo& my_foo)
{
my_foo.do_it();
}
If you really need a pointer (maybe because you can't change the implementation of DoSomething), then you can simply take the pointer to an automatic:
Foo foo;
DoSomething(&foo);
If you need to dynamically allocate the Foo object, things get a little trickier. Someone made the new operation private for a reason. Probably a very good reason. There may be a factory method on Foo like:
class Foo
{
public:
static Foo* MakeFoo();
private:
};
..in which case you should call that. Otherwise you're going to have to edit the implementation of Foo itself, and that might not be easy or a good thing to do.
Be careful about breaking the Concrete Data Type idiom.
You are trying to circumvent the fact that the new operator has been made private, i.e. the Concrete Data Type idiom/pattern. The new operator was probably made private for specific reasons, e.g. another part of the design may depend on this restriction. Trying to get around this to dynamically allocate an instance of the class is trying to circumvent the design and may cause other problems or other unexpected behavior. I wouldn't suggest trying to circumvent this without studying the code thoroughly to ensure you understand the impact to other parts of the class/code.
Concrete Data Type
http://users.rcn.com/jcoplien/Patterns/C++Idioms/EuroPLoP98.html#ConcreteDataType
Solutions
...
Objects that represent abstractions that live "inside" the program, closely tied to the computational model, the implementation, or the programming language, should be declared as local (automatic or static) instances or as member instances. Collection classes (string, list, set) are examples of this kind of abstraction (though they may use heap data, they themselves are not heap objects). They are concrete data types--they aren't "abstract," but are as concrete as int and double.
class ScopedLock
{
private:
static void * operator new (unsigned int size); // Disallow dynamic allocation
static void * operator new (unsigned int size, void * mem); // Disallow placement new as well.
};
int main (void)
{
ScopedLock s; // Allowed
ScopedLock * sl = new ScopedLock (); // Standard new and nothrow new are not allowed.
void * buf = ::operator new (sizeof (ScopedLock));
ScopedLock * s2 = new(buf) ScopedLock; // Placement new is also not allowed
}
ScopedLock object can't be allocated dynamically with standard uses of new operator, nothrow new, and the placement new.
The funny thing that would happen results from the constructor not being called for *foo. It will only work if it is a POD (simple built-in types for members + no constructor). Otherwise, when using assignment, it may not work out right, if the left-hand side is not already a valid instance of the class.
It seems, you can still validly allocate an instance on the heap with
Foo* p = ::new Foo;
To restrict how a class instance can be created, you will probably be better off declaring the constructor(s) private and only allow factory functions call them.
Wrap it:
struct FooHolder {
Foo foo;
operator Foo*() { return &foo; }
};
I don't have full understanding of the underlying code. If other things are ok, the code above is correct. Enough space will be allocated from malloc() and anything funny will not happen. But avoid using strange code and work straighforward:
Foo f;
Foo *pf = &f;

Calling a constructor to re-initialize object

is it possible to re-initialize an object of a class using its constructor?
Sort of. Given a class A:
A a;
...
a = A();
the last statement is not initialisation, it is assignment, but it probably does what you want.
Literally? Yes, by using placement new. But first you have to destruct the previously constructed object.
SomeClass object(1, 2, 3);
...
object.~SomeClass(); // destruct
new(&object) SomeClass(4, 5, 6); // reconstruct
...
// Final destruction will be done implicitly
The value of this does not go beyond purely theoretical though. Don't do it in practice. The whole thing is ugly beyond description.
It's possible, although it's a very bad idea. The reason why is that without calling the destructors on the existing object, you are going to leak resources.
With that major caveat, if you insist on doing it, you can use placement new.
// Construct the class
CLASS cl(args);
// And reconstruct it...
new (&cl) CLASS(args);
In C++11, you can do this:
#include <type_traits>
template <class T, typename... Args>
void Reconstruct(T& x, Args&&... args)
{
static_assert(!std::has_virtual_destructor<T>::value, "Unsafe");
x.~T();
new (&x) T(std::forward<Args>(args)...);
}
This allows you to use Reconstruct passing arbitrary constructor parameters to any object. This can avoid having to maintain a bunch of Clear methods, and bugs that can easily go unnoticed if at some point the object changes, and the Clear method no longer matches the constructor.
The above will work fine in most contexts, but fail horribly if the reference is to a base within a derived object that has a virtual destructor. For this reason, the above implementation prevents use with objects that have a virtual destructor.
Short answer:
No. If part of your object's intended behavior is to be initialized several times, then the best way to implement this is through an accessible initialization method. The constructor of your class can simply defer to this method.
class C1 {
public:
C1(int p1, int p2) {
Init(p1,p2);
}
void Init(int p1, int p2) { ... }
};
Nitpicker corner:
Is there some incredibly evil way to call a constructor in C++ after an object is created? Almost certainly, this is C++ after all. But it's fundamentally evil and it's behavior is almost certainly not defined by the standard and should be avoided.
No, constructors are only called when the object is first created. Write a new method to do it instead.
Edit
I will not acknowledge placement new, because I don't want to have to get a pet raptor for work.
See this comic, but think of the topic on hand...
Yes you can cheat and use placement new.
Note: I do not advice this:
#include <new>
reInitAnA(A& value)
{
value.~A(); // destroy the old one first.
new (&value) A(); // Call the constructor
// uses placement new to construct the new object
// in the old values location.
}
I usually write the following in modern C++ :
SomeClass a;
...
a = decltype(a)();
It may be not the most effective way, as it effectively constructs another object of the same type of a and assigns it to a, but it works in most cases, you don't have to remember the type of a, and it adapts if the type changes.
Instead of destructing and reinitializing as suggested by some of the answers above, it's better to do an assignment like below. The code below is exception safe.
T& reinitialize(int x, int y)
{
T other(x, y);
Swap(other); // this can't throw.
return *this;
}
May-be not what you have in mind, but since you didn't mention what it is for, I suppose one answer would be that you'd do it by controlling scope and program flow.
For example, you wouldn't write a game like this:
initialize player
code for level 1
...
reinitialize player
code for level 2
...
etc
Instead you'd strive for:
void play_level(level_number, level_data) {
Player player; //gets "re-initialized" at the beginning of each level using constructor
//code for level
}
void game() {
level_number = 1;
while (some_condition) {
play_level(level_number, level_data);
++level_number;
}
}
(Very rough outline to convey the idea, not meant to be remotely compilable.)
If you really must do this I strongly encourage creating a reset method for this:
class A
{
...
public:
reset() { *this= A() };
}
The above requires A to be copy and move assignable.
That is because the initial unoptimized version will copy from a temp. However copy elision may remove this step.
The behavior of A::reset() is always well defined. It replace the existing data in a valid A instance with a data from a new one. Of course any sub-class of A will still need to define its own version if you wanted its data re-initialized as well. However, failure to do so does not in and of itself invoke undefined or unspecified behavior. It simply means that only whatever memory A uses for its members will be reset. Even the involvement of virtual functions and/or virtual inheritance doesn't change this. Although the usual caveats of using such things apply.
Raw pointers will not be deleted by the above so they will need to be put into a std::shared_ptr or similar construct so the will self destruct when no longer needed.
While most answers are reinitializing an object in two steps; first, creating an initial object, and second creating another object and swapping it with the first one using placement new, this answer covers the case that you first create a pointer to an empty object and later allocate and construct it:
class c *c_instance; // Pointer to class c
c_instance = new c(arg1, ..., argn) // Allocate memory & call the proper constructor
// Use the instance e.g. c->data
delete c_instance; // Deallocate memory & call the destructor
Yes , it is possible.
If you create a method that returns a new object.
#include "iostream"
class a // initialize class
a getNewA(a object){// Create function to return new a object
a new_object(/*Enter parameters for constructor method*/);
return new_object;
}

Ensuring pointer is not deleted

I've stumbled onto something I can't figure out, so I think I'm missing something in the greater C++ picture.
In short, my question is: how to keep a mutable, non-deletable, possibly NULL instance of an object in a class.
The longer version is:
I have the following scenario: a bunch of classes (which I can change slightly, but not thoroughly refactor), most of which need to use an object. This object, while mutable, is managed by someone else so it must not be deleted.
Some of the classes in the bunch do not need such an object - they reuse code from other classes, but through the available parameters supplied to these classes it is guaranteed that even if an object is supplied, it will not be used.
The current implementation uses a pointer-to-const-object (const Obj *). This, in turn, means all the object's methods must be const and most fields mutable. This is a messy solution since the fields declared mutable are available for inspection (so quite the opposite of the c++ lite entry here). It also only partially solves the "do-not-delete-this-here" issue (compiler does not complain but a const in front of the object is an indication).
If I used a reference to this object, I'd force some callers to create a "dummy" object and provide it to the class they are instantiating. This is also messy, besides being a waste of resources. I cannot create a global object to can stand in for a "NULL" reference due to project restrictions.
I feel that the reference is the tool I need, but I cannot refactor the classes involved to such an extent as to have the object disappear from their implementations where it is not used (it can be done, but it is not simple and it would not be fast). So I want to implement something simpler, which will just draw an alarm signal if anyone tries to misuse this object, but keeps my object mutable.
The best solution I can think of is using a const-pointer-to-object (Obj * const) - this does not make the compiler complain, but I have my mutable object and a sort-of alarm signal -through the const - in place as well.
Does anyone have a better idea ?
I've traditionally seen these kind of scenarios implemented using a shared_ptr/weak_ptr combo. See here.
The owner/deleter would get a
boost::shared_ptr<T>
Your class would get a
boost::weak_ptr<T>
To reassign the weak ptr, simply reassign the pointer:
void MyClass::Reassign(boost::weak_ptr<T> tPtr)
{
m_tPtr = tPtr;
}
To use the weak ptr, first check to see if it's still around:
void MyClass::Use()
{
boost::shared_ptr<T> m_temporarySharedPtr = m_tPtr.lock();
if (m_temporarySharedPtr)
{
//...
}
}
The weak ptr can be made "NULL" by reseting it, or assigning it to an empty shared_ptr
void MyClass::MakeNull()
{
m_tPtr.reset();
}
You can make the destructor of that object private. That will trigger compile time error on attemp to delete object. Also you should allow restcted code to delete object by using friends mechanism or member function.
You can put a wrapper around the pointer to allow modification but not deletion:
template <typename T> class Wrapper
{
public:
Wrapper(T *p=0) : pointer(p) {}
T *operator->() {return pointer;}
T const *operator->() const {return pointer;}
operator bool() const {return pointer;}
private:
T *pointer;
};
You can use this just like a pointer to the template type in some contexts, but can't call delete on it. The wrapped type must be a struct or class type (i.e. a type where -> makes sense). Then one of your classes that uses, but doesn't manage the lifetime of, the object would look a bit like this:
class User
{
public:
void Assign(Object *o) {object = o;}
void UseObject() {if (object) object->Use();}
private:
Wrapper<Object> object;
};
Technically, you can still get at the raw pointer, but the code to do it is very wrong-looking:
delete wrapper.operator->();
Sounds like a case for a shared_ptr.
An alternative (if allowed by your restircitons) would be to create a dummy object similar to a shared pointer to act as a wrapper between the object in question and your classes.
Your classes can attempt to delete this object if they wish, but it itself will leave the original object untouched. Overload the * operator and you can use it transparently.
something like this?...
the Obj class is an aggregation of your new class, you point at it with an Obj* cont pObj, which you set up at the creation of your new class (or leave as 0 if it's not used), you then check pObj before calling any of its functions?
if ( pObj ){ pObj->foo(); }
if the function foo's incorrectly defined as mutable then you need to fix its declaration.
your new class isn't responsible for cleaning up/deleting the Obj class.

Pointer container class which can't be copied by value

I need a smart pointer for my project which can be send to several methods as parameter. I have checked auto_ptr and shared_ptr from boost. But IMO, that is not suitable for my requirements. Following are my findings
auto_ptr : When passed to another method, ownership will be transferred and underlying pointer will get deleted when that method's scope ends. We can workaround this by passing auto_ptr by reference, but there is no compile time mechanism to ensure it is always passed by reference. If by mistake, user forgot to pass a reference, it will make problems.
boost::shared_ptr : This looks promising and works correctly for my need. But I feel this is overkill for my project as it is a very small one.
So I decided to write a trivial templated pointer container class which can't be copied by value and take care about deleting the underlying pointer. Here it is
template <typename T>
class simple_ptr{
public:
simple_ptr(T* t){
pointer = t;
}
~simple_ptr(){
delete pointer;
}
T* operator->(){
return pointer;
}
private:
T* pointer;
simple_ptr(const simple_ptr<T>& t);
};
Is this implementation correct? I have made copy constructor as private, so that compiler will alert when someone tries to pass it by value.
If by chance the pointer is deleted, delete operation on the destructor will throw assertion error. How can I workaround this?
I am pretty new to C++ and your suggestion are much appreciated.
Thanks
Please use boost::scoped_ptr<> as suggested by Martin York, because it:
Does exactly what you want (it's a noncopyable pointer)
Has no overhead above that of a standard C pointer
Has been carefully crafted by super-intelligent C++ wizards to make sure it behaves as expected.
While I can't see any problems with your implementation (after applying the changes suggested by ChrisW), C++ has many dark corners and I would not be surprised if there is some obscure corner case which you, I and the others here have failed to spot.
What you have done is boost::scoped_ptr
Please also read comment by j_random_hacker.
Is this implementation correct? I have made copy constructor as private ...
You could do the same for the assignment operator:
simple_ptr& operator=(const simple_ptr<T>& t);
A const version of the dereference operator might be useful too, and, smart pointers usually define the other kind of dereference operator as well:
const T* operator->() const { return pointer; }
const T& operator*() const { return *pointer; }
T& operator*() { return *pointer; }
If by chance the pointer is deleted, delete operation on the destructor will throw assertion error. How can I workaround this?
Do you mean, if I do this:
//create instance
Car* car = new Car;
//assign to smart ptr
simple_ptr<Car> ptr(car);
//explicit delete
delete car;
//... assertion when ptr is destroyed ...
A way (I don't know if it's a good way) to prevent that is to declare the constructor, and/or the destructor, and/or the delete operator of the T class as private, and say that simple_ptr is a friend of the T class (so that only the simple_ptr class can create and/or destroy and/or delete instances of T).
Marking the new operator as private in T class seems to be impossible as I have to modify all the classes which will be used with simple_ptr
Yes that's true: to do my suggestion immediately above, you would need to modify the class definitions.
If your question is "how can I make double deletes impossible, without modifying class definitions?" then I think the answers are:
You can't: it's up the application code (which uses these classes) to be careful
You can: by providing your own heap manager i.e. your own implementation of global operator new and global operator delete and, in your smart_ptr code, interrogate your heap manager to see whether this incarnation of this pointer is still allocated, before you delete it
To answer your first question, the best assurance you can get that this is correct is to implement a test harness around it to do some simple task, and make sure you get the behavior you expect. For me, that is far better comfort the code is right than the opinion of some random person reading it.
As for your second question, you work around delete throwing an assertion error by setting pointer to some marker value after you delete it the first time. Something like:
if (pointer) {
delete pointer;
pointer = NULL;
} else {
error("Attempted to free already freed pointer.");
}
The problem you're going to run into here is that your overloaded -> operator returns the value of the pointer, which means whoever you return this to can also call delete, causing the check I propose above not to work. For example:
simple_ptr<int> myPtr = someIntPointer;
...
delete myPtr.operator->(); /* poof goes your pointered memory region */
I might recommend that you not rely on the operator-> overloading, and just require that those using this class call a method that dereferences the pointer internally before passing that value back to the user.
Hope this helps.
You should user a boost::scoped_ptr<> as has been mentioned already.
In general though, if you need to make a class non-copyable, you should inherit from boost::noncopyable, i.e.
#include <boost/utility.hpp>
class myclass : boost::noncopyable
{
...
};
This does all the work of making it non-copyable and is nicely self-documenting.
You've got two choices:
boost::scoped_ptr already detailed by j_random_hacker, because it's non-copyable (doesn't share ownership like shared_ptr) and non-movable (doesn't transfer ownership like auto_ptr. auto_ptr has a copy constructor, but that one does not copy. It moves the original pointer to *this). boost::scoped_ptr is exactly what you need.
const auto_ptr doesn't allow transfer of ownership. And take your parameter by reference to const (auto_ptr<T> const&). If the writer of a function accepts by value instead, it still won't work if you try passing a const auto_ptr, because its copy constructor needs a non-const auto_ptr.
Until C++1x, boost::scoped_ptr is the best choice for your needs, or a const auto_ptr if you have to use official standard stuff (read this). In C++1x, you can use std::unique_ptr as a better alternative to auto_ptr, because you have to explicitly state when you want to transfer ownership. Trying to copy it will result in a compile time error. unique_ptr is detailed a little in this answer.
I've seen sometimes usage of simple DISABLE_COPY macros:
#define DISABLE_COPY(Class) \
Class(const Class &); \
Class &operator=(const Class &);
So it's a common practice to define copy constructor and assignment operator as private for your task.

How do I prevent a class from being allocated via the 'new' operator? (I'd like to ensure my RAII class is always allocated on the stack.)

I'd like to ensure my RAII class is always allocated on the stack.
How do I prevent a class from being allocated via the 'new' operator?
All you need to do is declare the class' new operator private:
class X
{
private:
// Prevent heap allocation
void * operator new (size_t);
void * operator new[] (size_t);
void operator delete (void *);
void operator delete[] (void*);
// ...
// The rest of the implementation for X
// ...
};
Making 'operator new' private effectively prevents code outside the class from using 'new' to create an instance of X.
To complete things, you should hide 'operator delete' and the array versions of both operators.
Since C++11 you can also explicitly delete the functions:
class X
{
// public, protected, private ... does not matter
static void *operator new (size_t) = delete;
static void *operator new[] (size_t) = delete;
static void operator delete (void*) = delete;
static void operator delete[](void*) = delete;
};
Related Question: Is it possible to prevent stack allocation of an object and only allow it to be instiated with ‘new’?
I'm not convinced of your motivation.
There are good reasons to create RAII classes on the free store.
For example, I have an RAII lock class. I have a path through the code where the lock is only necessary if certain conditions hold (it's a video player, and I only need to hold the lock during my render loop if I've got a video loaded and playing; if nothing's loaded, I don't need it). The ability to create locks on the free store (with an unique_ptr) is therefore very useful; it allows me to use the same code path regardless of whether I have to take out the lock.
i.e. something like this:
unique_ptr<lock> l;
if(needs_lock)
{
l.reset(new lock(mtx));
}
render();
If I could only create locks on the stack, I couldn't do that....
#DrPizza:
That's an interesting point you have. Note though that there are some situations where the RAII idiom isn't necessarily optional.
Anyway, perhaps a better way to approach your dilemma is to add a parameter to your lock constructor that indicates whether the lock is needed. For example:
class optional_lock
{
mutex& m;
bool dolock;
public:
optional_lock(mutex& m_, bool dolock_)
: m(m_)
, dolock(dolock_)
{
if (dolock) m.lock();
}
~optional_lock()
{
if (dolock) m.unlock();
}
};
Then you could write:
optional_lock l(mtx, needs_lock);
render();
In my particular situation, if the lock isn't necessary the mutex doesn't even exist, so I think that approach would be rather harder to fit.
I guess the thing I'm really struggling to understand is the justification for prohibiting creation of these objects on the free store.