Size of class instance - c++

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;

Related

Is it bad to recreate stack object after injected to class as pointer?

// Example program
#include <iostream>
class Foo{
public:
Foo(int a):a(a){}
void print(){
printf("%d\n",a);
}
private:
int a;
};
class Bar{
public:
Bar(Foo* foo):foo(foo){}
void print(){
foo->print();
}
private:
Foo* foo;
};
int main()
{
Foo f = {10};
Bar b(&f);
b.print();
f = {20};
b.print();
}
In the code above a Foo object shared with a Bar object can be recreated without that Bar knows about it.
Imagine I have to inject the bar object into a third class. Now I can update the foo dependency without having to create a new object of bar and the third class.
Is this pattern commonly used or not and does it violate some of the OOP principles?
I don't think the code does what you think it does.
I've added the default constructors and assign/operators to your Foo class with some logging to see what happens. These constructors are added automatically by the compilers unless you disable them explicitly. See the output here.
What happens in
f = {20};
is that you construct a different Foo object then you move-assign it to the original instance.
In this case it's equivalent to
f.a = 20; // Assuming we make a public.
In conclusion.
If your usage is just to change fields in the existing instance (through assign operators in this case). Then everything should work fine. This shouldn't necessarily invalidate OOP principles, unless you have assumptions that Bar.foo is constant or doesn't change. This is usually called composition and it's fairly common (your UI will contain various button instances that might be modified from other sources).
If you expect to change the implementation (say Foo is a virtual class and you want a different derivation to be substituted) then in your code you will need to have Foo* f = new Foo(10);. You will have copy of the pointer in b and the assignment will create a new class, that will not be update in b (something like f = new FooDerived(20);.
To make it work you need a Provider class (this is a OOP pattern). This would be something that gives you a Foo. The simplest one would be Foo**. But it's likely better to have something a bit more customizable.
That said for any serious work try to stay away from naked pointers (Foo*). Use unique_ptr or shared_ptr as appropriate to save yourself a lot of problems in the future.
Is this pattern commonly used or not and does it violate some of the OOP principles?
Yes, this is fairly common, and OK in your example.
You do have to be careful to ensure that f remains alive for the whole lifetime of b, which is the case in your example. If you were to copy b, you would also need to ensure the copy didn't outlive f.
The nice thing about the local variables of a function func is that they outlive any local variables of functions that func calls. Thus the local variables of main live for (almost) the whole program, only global variables outlive them.
Is this pattern commonly used or not and does it violate some of the OOP principles?
I would say that such a structure should be carefully used.
Actually, in Bar you are just copying the pointer value. But if the given Foo created on the stack goes out of scope, then Bar is storing a dangling pointer.
Trying to dereference a dangling pointer is Undefined Behaviour.
Is it bad to recreate stack object after injected to class as pointer?
Actually, as #DanielLangr mentioned, you did not have "recreated" the object, you just have reassigned its contents, so the object lifetime has not ended.
In your case, you're still fine.

Trying to store an object in an array but then how to call that object's methods?

I'm not a very experienced c++ coder and this has me stumped. I am passing a object (created elsewhere) to a function, I want to be able to store that object in some array and then run through the array to call a function on that object. Here is some pseudo code:
void AddObject(T& object) {
object.action(); // this works
T* objectList = NULL;
// T gets allocated (not shown here) ...
T[0] = object;
T[0].action(); // this doesn't work
}
I know the object is passing correctly, because the first call to object.action() does what it should. But when I store object in the array, then try to invoke action() it causes a big crash.
Likely my problem is that I simply tinkered with the .'s and *'s until it compiled, T[0].action() compliles but crashes at runtime.
The simplest answer to your question is that you must declare your container correctly and you must define an appropriate assigment operator for your class. Working as closely as possible from your example:
typedef class MyActionableClass T;
T* getGlobalPointer();
void AddInstance(T const& objInstance)
{
T* arrayFromElsewhere = getGlobalPointer();
//ok, now at this point we have a reference to an object instance
//and a pointer which we assume is at the base of an array of T **objects**
//whose first element we don't mind losing
//**copy** the instance we've received
arrayFromElsewhere[0] = objInstance;
//now invoke the action() method on our **copy**
arrayFromElsewhere[0].action();
}
Note the signature change to const reference which emphasizes that we are going to copy the original object and not change it in any way.
Also note carefully that arrayFromElsewhere[0].action() is NOT the same as objInstance.action() because you have made a copy — action() is being invoked in a different context, no matter how similar.
While it is obvious you have condensed, the condensation makes the reason for doing this much less obvious — specifying, for instance, that you want to maintain an array of callback objects would make a better case for “needing” this capability. It is also a poor choice to use “T” like you did because this tends to imply template usage to most experienced C++ programmers.
The thing that is most likely causing your “unexplained” crash is that assignment operator; if you don't define one the compiler will automatically generate one that works as a bitwise copy — almost certainly not what you want if your class is anything other than a collection of simple data types (POD).
For this to work properly on a class of any complexity you will likely need to define a deep copy or use reference counting; in C++ it is almost always a poor choice to let the compiler create any of ctor, dtor, or assignment for you.
And, of course, it would be a good idea to use standard containers rather than the simple array mechanism you implied by your example. In that case you should probably also define a default ctor, a virtual dtor, and a copy ctor because of the assumptions made by containers and algorithms.
If, in fact, you do not want to create a copy of your object but want, instead, to invoke action() on the original object but from within an array, then you will need an array of pointers instead. Again working closely to your original example:
typedef class MyActionableClass T;
T** getGlobalPointer();
void AddInstance(T& objInstance)
{
T** arrayFromElsewhere = getGlobalPointer();
//ok, now at this point we have a reference to an object instance
//and a pointer which we assume is at the base of an array of T **pointers**
//whose first element we don't mind losing
//**reference** the instance we've received by saving its address
arrayFromElsewhere[0] = &objInstance;
//now invoke the action() method on **the original instance**
arrayFromElsewhere[0]->action();
}
Note closely that arrayFromElsewhere is now an array of pointers to objects instead of an array of actual objects.
Note that I dropped the const modifier in this case because I don’t know if action() is a const method — with a name like that I am assuming not…
Note carefully the ampersand (address-of) operator being used in the assignment.
Note also the new syntax for invoking the action() method by using the pointer-to operator.
Finally be advised that using standard containers of pointers is fraught with memory-leak peril, but typically not nearly as dangerous as using naked arrays :-/
I'm surprised it compiles. You declare an array, objectList of 8 pointers to T. Then you assign T[0] = object;. That's not what you want, what you want is one of
T objectList[8];
objectList[0] = object;
objectList[0].action();
or
T *objectList[8];
objectList[0] = &object;
objectList[0]->action();
Now I'm waiting for a C++ expert to explain why your code compiled, I'm really curious.
You can put the object either into a dynamic or a static array:
#include <vector> // dynamic
#include <array> // static
void AddObject(T const & t)
{
std::array<T, 12> arr;
std::vector<T> v;
arr[0] = t;
v.push_back(t);
arr[0].action();
v[0].action();
}
This doesn't really make a lot of sense, though; you would usually have defined your array somewhere else, outside the function.

How to reassign `this` pointer inside object member function?

I have an interesting question about C++ pointers.
You probably will think that I have to change my design, and avoid
doing what I am doing, and you are probably right.
But let's assume that I have a good reason to do it my way.
So this is the situation. I have a C++ class TestClass, and I have a pointer A of this type:
TestClass* A = new TestClass();
Among other things TestClass has this function:
void TestClass::Foo(){
TestClass* B = new TestClass();
...
}
This function creates object B of the same type and populates it with some data.
At the end of this function, I want pointer A to point at object B.
Anywhere outside this function it would look like A=B; inside this function
it could look like this = B
But as you know you cannot reassign "this" pointer.
Possible solutions:
Copy the memory:
memcpy(this, B, sizeof(TestClass));
This method works correctly. The function copies each bit of object B into object A.
Problem: if TestClass is a big object(and it is), it creates significant overhead in performance for multiple Foo calls.
Return a B pointer from the function and do something like this
Temp = A;
A=A->Foo();
freeMemory(Temp);
But this code looks stupid, and it makes function Foo very hard to use.
So the question is, how I can do this = B from inside a member function, without copying whole objects?
Use an extra level of indirection. Your TestClass can have a pointer that points to a class that contains all of its data.
class TestClass
{
private:
TestClassData* m_data;
};
void TestClass::Foo()
{
TestClassData* B = new TestClassData();
...
delete m_data;
m_data = B;
}
Just make sure your operator== returns true if the contents of m_data are equal.
how i can do this = B
You cannot.
One of the working solutions:
memcpy(this, B, sizeof(TestClass));
this method working correctly.
If TestClass is not a POD, this function doesn't work. You can't memcpy objects with virtual functions, for example. You'll blow away the vtable.
Inside of your function, you can do
*this = B;
Which make pretty the same copy operation.
Or you could also declare
Foo(TestClass &X);
And reassign X address inside.
You can't. this is defined by the standard as a TestClass * const.
To realize why, think about this code:
int main() {
TestClass A;
A.Foo();
return 0;
}
A is on the stack. How do you make an object on the stack 'refer' to something else?
The problem is that many pointers, not just A, can point to the old object. The this pointer is not A, although A contains a copy of it. The only way to do it is 1. reassign A, or 2. make a new pointer type that adds a level of indirection to your object so you can replace it without anyone knowing.
What you are doing is not good.
First off, you have function Foo that will:
Create and generate a new class
Reassign an existing class to the new class
So, why not just change the existing class into the class you want?
That said, you could make Foo static and take "take this manually":
void Foo(TestClass*& this)
{
delete this;
this = // ...
}
But that's equally nasty as your other solutions. We probably need more context to give you the best solution.
I'm pretty sure that you should look at smart pointers as a way to solve this problem. These essentially add an extra level of indirection (without changing the syntax clients use), and would allow you so change the actual object pointed to without informing the client.

Issues with C++ 'new' operator?

I've recently come across this rant.
I don't quite understand a few of the points mentioned in the article:
The author mentions the small annoyance of delete vs delete[], but seems to argue that it is actually necessary (for the compiler), without ever offering a solution. Did I miss something?
In the section 'Specialized allocators', in function f(), it seems the problems can be solved with replacing the allocations with: (omitting alignment)
// if you're going to the trouble to implement an entire Arena for memory,
// making an arena_ptr won't be much work. basically the same as an auto_ptr,
// except that it knows which arena to deallocate from when destructed.
arena_ptr<char> string(a); string.allocate(80);
// or: arena_ptr<char> string; string.allocate(a, 80);
arena_ptr<int> intp(a); intp.allocate();
// or: arena_ptr<int> intp; intp.allocate(a);
arena_ptr<foo> fp(a); fp.allocate();
// or: arena_ptr<foo>; fp.allocate(a);
// use templates in 'arena.allocate(...)' to determine that foo has
// a constructor which needs to be called. do something similar
// for destructors in '~arena_ptr()'.
In 'Dangers of overloading ::operator new[]', the author tries to do a new(p) obj[10]. Why not this instead (far less ambiguous):
obj *p = (obj *)special_malloc(sizeof(obj[10]));
for(int i = 0; i < 10; ++i, ++p)
new(p) obj;
'Debugging memory allocation in C++'. Can't argue here.
The entire article seems to revolve around classes with significant constructors and destructors located in a custom memory management scheme. While that could be useful, and I can't argue with it, it's pretty limited in commonality.
Basically, we have placement new and per-class allocators -- what problems can't be solved with these approaches?
Also, in case I'm just thick-skulled and crazy, in your ideal C++, what would replace operator new? Invent syntax as necessary -- what would be ideal, simply to help me understand these problems better.
Well, the ideal would probably be to not need delete of any kind. Have a garbage-collected environment, let the programmer avoid the whole problem.
The complaints in the rant seem to come down to
"I liked the way malloc does it"
"I don't like being forced to explicitly create objects of a known type"
He's right about the annoying fact that you have to implement both new and new[], but you're forced into that by Stroustrups' desire to maintain the core of C's semantics. Since you can't tell a pointer from an array, you have to tell the compiler yourself. You could fix that, but doing so would mean changing the semantics of the C part of the language radically; you could no longer make use of the identity
*(a+i) == a[i]
which would break a very large subset of all C code.
So, you could have a language which
implements a more complicated notion of an array, and eliminates the wonders of pointer arithmetic, implementing arrays with dope vectors or something similar.
is garbage collected, so you don't need your own delete discipline.
Which is to say, you could download Java. You could then extend that by changing the language so it
isn't strongly typed, so type checking the void * upcast is eliminated,
...but that means that you can write code that transforms a Foo into a Bar without the compiler seeing it. This would also enable ducktyping, if you want it.
The thing is, once you've done those things, you've got Python or Ruby with a C-ish syntax.
I've been writing C++ since Stroustrup sent out tapes of cfront 1.0; a lot of the history involved in C++ as it is now comes out of the desire to have an OO language that could fit into the C world. There were plenty of other, more satisfying, languages that came out around the same time, like Eiffel. C++ seems to have won. I suspect that it won because it could fit into the C world.
The rant, IMHO, is very misleading and it seems to me that the author does understand the finer details, it's just that he appears to want to mislead. IMHO, the key point that shows the flaw in argument is the following:
void* operator new(std::size_t size, void* ptr) throw();
The standard defines that the above function has the following properties:
Returns: ptr.
Notes: Intentionally performs no other action.
To restate that - this function intentionally performs no other action. This is very important, as it is the key to what placement new does: It is used to call the constructor for the object, and that's all it does. Notice explicitly that the size parameter is not even mentioned.
For those without time, to summarise my point: everything that 'malloc' does in C can be done in C++ using "::operator new". The only difference is that if you have non aggregate types, ie. types that need to have their destructors and constructors called, then you need to call those constructor and destructors. Such types do not explicitly exist in C, and so using the argument that "malloc does it better" is not valid. If you have a struct in 'C' that has a special "initializeMe" function which must be called with a corresponding "destroyMe" then all points made by the author apply equally to that struct as they do to a non-aggregate C++ struct.
Taking some of his points explicitly:
To implement multiple inheritance, the compiler must actually change the values of pointers during some casts. It can't know which value you eventually want when converting to a void * ... Thus, no ordinary function can perform the role of malloc in C++--there is no suitable return type.
This is not correct, again ::operator new performs the role of malloc:
class A1 { };
class A2 { };
class B : public A1, public A2 { };
void foo () {
void * v = ::operator new (sizeof (B));
B * b = new (v) B(); // Placement new calls the constructor for B.
delete v;
v = ::operator new (sizeof(int));
int * i = reinterpret_cast <int*> (v);
delete v'
}
As I mention above, we need placement new to call the constructor for B. In the case of 'i' we can cast from void* to int* without a problem, although again using placement new would improve type checking.
Another point he makes is about alignment requirements:
Memory returned by new char[...] will not necessarily meet the alignment requirements of a struct intlist.
The standard under 3.7.3.1/2 says:
The pointer returned shall be suitably aligned so that it can be converted to a
pointer of any complete object type and then used to access the object or array in the storage allocated (until
the storage is explicitly deallocated by a call to a corresponding deallocation function).
That to me appears pretty clear.
Under specialized allocators the author describes potential problems that you might have, eg. you need to use the allocator as an argument to any types which allocate memory themselves and the constructed objects will need to have their destructors called explicitly. Again, how is this different to passing the allocator object through to an "initalizeMe" call for a C struct?
Regarding calling the destructor, in C++ you can easily create a special kind of smart pointer, let's call it "placement_pointer" which we can define to call the destructor explicitly when it goes out of scope. As a result we could have:
template <typename T>
class placement_pointer {
// ...
~placement_pointer() {
if (*count == 0) {
m_b->~T();
}
}
// ...
T * m_b;
};
void
f ()
{
arena a;
// ...
foo *fp = new (a) foo; // must be destroyed
// ...
fp->~foo ();
placement_pointer<foo> pfp = new (a) foo; // automatically !!destructed!!
// ...
}
The last point I want to comment on is the following:
g++ comes with a "placement" operator new[] defined as follows:
inline void *
operator new[](size_t, void *place)
{
return place;
}
As noted above, not just implemented this way - but it is required to be so by the standard.
Let obj be a class with a destructor. Suppose you have sizeof (obj[10]) bytes of memory somewhere and would like to construct 10 objects of type obj at that location. (C++ defines sizeof (obj[10]) to be 10 * sizeof (obj).) Can you do so with this placement operator new[]? For example, the following code would seem to do so:
obj *
f ()
{
void *p = special_malloc (sizeof (obj[10]));
return new (p) obj[10]; // Serious trouble...
}
Unfortunately, this code is incorrect. In general, there is no guarantee that the size_t argument passed to operator new[] really corresponds to the size of the array being allocated.
But as he highlights by supplying the definition, the size argument is not used in the allocation function. The allocation function does nothing - and so the only affect of the above placement expression is to call the constructor for the 10 array elements as you would expect.
There are other issues with this code, but not the one the author listed.

How to prevent an object being created on the heap?

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?