I am currently trying to get into writing proper C++ code (getting it running was ok for some small prototypes, but it's been ugly).
I recently realized the difference of heap and stack instantiation (O m = new O() vs. O m()).
Now I have a class, where the header file defines a variable, which holds an table definition.
ChunkLoader.hpp:
TablePartion *tablePartial_;
ChunkLoader.cpp:
ChunkLoader() { tablePartial_ = new TablePartial(true, 0, 1); }
Now I want to instantiate the tablePartial on the stack, but I cannot use:
TablePartial tablePartial_(true, 0, 1);
I am totally blind? How can I allocate tablePartial_ on the stack?
Or I am getting it totally wrong, and I cannot use in the constructor since it would be out of scope after the constructor and thus be freed? But since I read that stack variables are better performance-wise, I'd like to use stack instantiation (and getting red of delete).
Main reason: stack overflow told me to get rid of pointers when ever possible. :)
To start off, you should probably avoid the terms "on the stack" or "on the heap", they're implementation details that have nothing to do with the concepts being discussed. Instead, we discuss the lifetime of the object, in terms of automatic (which more or less correlates with the stack), dynamic (which more or less correlates with the heap), static (which more or less correlates with globals), and thread (which is a thread-specific global).
In answer to your specific question, you can use constructor initializers to initialize your variable:
ChunkLoader()
: tablePartial_(true, 0, 1)
{
}
Since the class declaration is:
class MyClass
{
SomeOtherClass x;
};
x is contained in MyClass completely (it's not a pointer to SomeOtherClass).
Ergo, when creating an object MyClass on the stack, x will also be on the stack, and when creating an object MyClass on the heap, x will also be on the heap.
EDIT:
As I understood it, you want to allocate x on the stack. To do this, any instance of MyClass must also be on the stack. For this, you can make the new operator private:
class MyClass
{
SomeOtherClass x;
private:
void* operator new(size_t);
};
If you haven't used the word "new" in C++ (avoiding malloc and other C/OS calls for this conversation), then you haven't dynamically allocated memory on the "heap".
Everything you create in main() and the functions called therein goes on the stack if new isn't used. When you enter a new function call, you get a new stack frame, and all variables declared as so:
void foo() {
int x;
std::string y;
}
are created on the stack.
You can even get a "pointer" to a stack based object so you can use it polymorphically just like a pointer to a heap object:
//These should be "classes" with private/public hiding but I'm being lazy.
struct MyClass {
int x;
virtual void foo();
};
//These should be "classes" with private/public hiding but I'm being lazy.
struct MyClassDerived : MyClass {
void foo() { std::cerr << "foo called!" << std::endl; }
};
int main() {
MyClassDerived x;
MyClass* = &x;
x->foo();
}
Related
I am new to c++ so question would be elementary.
Lets say I have defined a class Foo and I create a vector of vectors in the following code:
namespace testme {
class Foo {
public:
Foo(int x): x_(x) { };
static vector<vector<int>> ReturnVecOfInts(int num) {
vector<vector<int>> ret(num);
for (int i = 0; i < num; i++) {
vector<int> tmp;
ret.push_back(tmp);
}
return ret;
}
}
When i call:
Foo::ReturnVecOfInts(5)
Is the vector of vectors created on heap or the stack. The reference is on the stack but I want to know whether it points to the heap since i want to return this object from a function.
This is important to me because clearly if these are allocated on the stack the vector of vectors would go out of scope and not usable outside the called function.
You're probably overthinking.
In your case, you're safe in code like this:
Foo f = Bar::GetFoo();
When you return objects from functions, in general, there may occur various optimizations (e.g. RVO, NRVO, etc.), but the bottom line is that your f object is safe to use.
Even if inside Foo you have a data member like std::vector which usually allocates its memory from the heap (you can customize this behavior using custom allocators), thanks to copy constructors, move constructors, destructor, etc. you are totally safe in returning it from functions, or copying Foo instances around.
EDIT I noted that you changed your code after I wrote my answer, returning a vector<vector<int>> instead of Foo. Again, what I wrote still applies.
I am attempting to use C++ for AVR programming using gcc-avr. The main issue is that there is no libc++ available and the implementation does not define any of the new or delete operators. Similarly there is no header to include using placement new is not an option.
When attempting to allocate a new dynamic object I am tempted to just do this:
Class* p = reinterpret_cast<Class*>(malloc(sizeof(Class)));
p->Init();
where Init() manually initializes all internal variables. But is this safe or even possible?
I have read that object construction in C++ is somewhat complex but without new or delete how do I initialize a dynamically allocated object?
To expand on the above question.
Using standard g++ and placement new it is possible to subvert constructors in two ways, assuming that C++ uses the same straightforward ways of alligning memory as C (code example below).
Using placement new to initialize any allocated memory.
Initialize allocated memory directly using class methods.
Of course this only holds if the assumptions are true that:
Memory layout of an object is fixed at compile time.
Memory allocation is only concerned with class variables and observers normal C rules (allocated in order of declaration aligned to memory boundary).
If the above holds could I not just allocated memory using malloc and use a reinterpret_cast to convert to the correct class and initialize it manually? Of course this is both non-portable and hack-ish but the only other way I can see is to work around the problem and not use dynamically allocated memory at all.
Example:
Class A {
int i;
long l;
public:
A() : i(1), l(2) {}
int get_i() { return i; }
void set_i(int x) { i = x; }
long get_l() { return l; }
void set_l(long y) { l = y; }
};
Class B {
/* Identical to Class A, except constructor. */
public B() : i(3), l(4) {}
};
int main() {
A* a = (A*) ::operator new(sizeof(A));
B* b = (B*) ::operator new(sizeof(B));
/* Allocating A using B's constructor. */
a = (A*) new (a) B();
cout << a->get_i() << endl; // prints 3
cout << a->get_l() << endl; // prints 4
/* Setting b directly without constructing */
b->set_i(5);
b->set_l(6);
cout << b->get_i() << endl; // prints 5
cout << b->get_l() << endl; // prints 6
If your allegedly C++ compiler does not support operator new, you should be able to simply provide your own, either in the class or as a global definition. Here's a simple one from an article discussing operator new, slightly modified (and the same can be found in many other places, too):
void* operator new(size_t sz) {
void* mem = malloc(sz);
if (mem)
return mem;
else
throw std::bad_alloc();
}
void operator delete(void* ptr) {
free(ptr);
}
A longer discussion of operator new, in particular for class-specific definitions, can also be found here.
From the comments, it seems that given such a definition, your compiler then happily supports the standard object-on-heap creations like these:
auto a = std::make_shared<A>();
A *pa = new A{};
The problem with using Init methods as shown in the code snippet in your question is that it can be a pain to get that to work properly with inheritance, especially multiple or virtual inheritance, at least when something during object construction might throw. The C++ language has elaborate rules to make sure something useful and predictable happens in that situation with constructors; duplicating that with ordinary functions probably will get tricky rather fast.
Whether you can get away with your malloc()-reinterprete_cast<>-init() approach depends on whether you have virtual functions/inheritance. If there is nothing virtual in your class (it's a plain old datatype), your approach will work.
However, if there is anything virtual in it, your approach will fail miserably: In these cases, C++ adds a v-table to the data layout of your class which you cannot access directly without going very deep into undefined behavior. This v-table pointer is usually set when the constructor is run. Since you can't safely mimic the behavior of the constructor in this regard, you must actually call a constructor. That is, you must use placement-new at the very least.
Providing a classless operator new() as Christopher Creutzig suggests, is the easiest way to provide full C++ functionality. It is the function that is used internally by new expressions to provide the memory on which the constructors can be called to provide a fully initialized object.
One last point of assurance: as long as you do not use a variable length array at the end of a struct like this
typedef struct foo {
size_t arraySize;
int array[];
} foo;
the size of any class/struct is entirely a compile time constant.
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;
Is it always necessary to allocate memory from the heap to facilitate dynamic polymorphism? All the examples i've come across so far point to the same.
Dynamic memory allocation is usually avoided in real-time-programming.So,is there any disadvantage of using the stack for dynamic polymorphism as shown in the code below.
class Base
{
public:
virtual void Display()= 0;
};
class Derived:public Base
{
public:
void Display()
{
cout << "In derived" << endl;
}
};
int main()
{
Base* base;
Derived derived1;
base = &derived1;
base->Foo();
return 0;
}
A better example would be:
void func(Base &base);
int main()
{
Derived derived;
func(derived);
return 0;
}
The use of polymorphism doesn't have to be near where the object is created on the stack.
A lot of our unit-testing code these days looks roughly like:
void test()
{
MockObject mockObj;
RealObject objectToBeTested(mockObj);
// Do tests
}
This depends intimately on polymorphism, but creates objects on the stack.
You don't have to use the heap if you want to use polymorphism, as you pointed out in your question. But you often have no other choice. Small contrived example:
void doSomething(int what) {
// figure out which implementation to create
Base * b;
if(doA) {
b = new ConcreteA; // 1a
} else if(doB) {
b = new ConcreteB; // 1b
}
...
b->...; // 2
}
You can't use the stack, because at the moment you know what to do, 1a and 1b, every storage you get from the stack will be reclaimed when that scope is left again. You have to use the heap because you need some storage that lasts that local scope.
Some libraries advertise with them being able to not use the heap, but still behave polymorphic. They usually do that with placement new:
void doSomething(int what) {
// allocate form *the stack*, outside the if blocks, so this
// storage lasts until the function returns
char buffer[MAX(sizeof (ConcreteA), sizeof(ConcreteB))];
if(doA) {
new (buffer) ConcreteA; // 1a
} else if(doB) {
new (buffer) ConcreteB; // 1b
}
Base *b = static_cast<Base*>(static_cast<void*>(buffer));
b->...; // 2
}
The new calls in 1a and 1b now use the buffer created on the stack as the storage for the created object. So, no heap memory allocation is required anymore. That form of allocation has the main disadvantage that it's currently not possible in C++ to tell whether the buffer is correctly aligned for the types ConcreteA and ConcreteB though. So, it can be that the array is aligned on a 2 byte boundary, but the objects are required to be created on a 4 byte boundary, resulting in undefined behavior when you try to create those objects into that buffer.
Boost.Function is one of those libraries that use such a placement new approach to create objects of polymorphic types without using heap allocation using a small buffer (hence, what it does is called small buffer optimization).
There's no problem with using the stack.
When you're using the stack then you often know exactly what type of object it is ... so there's no need for the method to be virtual, it's harmless but unnecessary, for example:
Derived derived;
derived.Foo();
However, the object (which exists on the stack) can be passed to subroutines which accept a superclass instance as a parameter (in which case the fact that it's a subclass is useful/used):
void foo(Base* base)
{
...
}
void test()
{
Derived derived;
foo(&derived);
}
I think this is perfectly fine. The only possible drawback is the limited scope of an object created on the stack, but that's not necessarily related to polymorphism.
Using the stack will be fine for the simple case you show. One real time issue with dynamic polymorphism vs static is the added time to to go through the indirection of the method call. Which is an extra memory access per method call.
You need to explain more about what your doing to analyze other factors, e.g. is the stack frame guaranteed to be in physical memory, sharing, number of instances, lifespan of instances
I'm not new to programming, but after working in Java I'm coming back to C++ and am a little confused about class variables that aren't pointers. Given the following code:
#include <iostream>
#include <map>
using namespace std;
class Foo {
public:
Foo() {
bars[0] = new Bar;
bars[0]->id = 5;
}
~Foo() { }
struct Bar {
int id;
};
void set_bars(map<int,Bar*>& b) {
bars = b;
}
void hello() {
cout << bars[0]->id << endl;
}
protected:
map<int,Bar*> bars;
};
int main() {
Foo foo;
foo.hello();
map<int,Foo::Bar*> testbars;
testbars[0] = new Foo::Bar;
testbars[0]->id = 10;
foo.set_bars(testbars);
foo.hello();
return(0);
}
I get the expected output of 5 & 10. However, my lack of understanding about references and pointers and such in C++ make me wonder if this will actually work in the wild, or if once testbars goes out of scope it will barf. Of course, here, testbars will not go out of scope before the program ends, but what if it were created in another class function as a function variable? Anyway, I guess my main question is would it better/safer for me to create the bars class variable as a pointer to the map map?
Anyway, I guess my main question is
would it better/safer for me to create
the bars class variable as a pointer
to the map map?
No. C++ is nothing like Java in this and may other respects. If you find yourself using pointers and allocating new'd objects to them a lot, you are probably doing something wrong. To learn the right way to do things, I suggest getting hold of a copy of Accelerated C++ by Koenig & Moo,
The member variable bars is a separate instance of a "dictionary"-like/associative array class. So when it is assigned to in set_bars, the contents of the parameter b are copied into bars. So there is no need to worry about the relative lifetimes of foo and testbars, as they are independent "value-like" entites.
You have more of a problem with the lifetimes of the Bar objects, which are currently never going to be deleted. If you add code somewhere to delete them, then you will introduce a further problem because you are copying the addresses of Bar objects (rather than the objects themselves), so you have the same object pointed to by two different maps. Once the object is deleted, the other map will continue to refer to it. This is the kind of thing that you should avoid like the plague in C++! Naked pointers to objects allocated with new are a disaster waiting to happen.
References (declared with &) are not different from pointers with regard to object lifetimes. To allow you to refer to the same object from two places, you can use either pointers or references, but this will still leave you with the problem of deallocation.
You can get some way toward solving the deallocation problem by using a class like shared_ptr, which should be included with any up-to-date C++ environment (in std::tr1). But then you may hit problems with cyclical pointer networks (A points to B and B points to A, for example), which will not be automatically cleaned up.
For every new you need a corresponding delete.
If you try and reference the memory after you call delete - where ever that is - then the program will indeed "barf".
If you don't then you will be fine, it's that simple.
You should design your classes so that ownership of memory is explicit, and that you KNOW that for every allocation you are doing an equal deallocation.
Never assume another class/container will delete memory you allocated.
Hope this helps.
In the code below you can pass map of Bars and then will be able to modify Bars outside of the class.
But. But unless you call set_bars again.
It is better when one object is responsible for creation and deletion of Bars. Which is not true in your case.
If you want you can use boost::shared_ptr< Bars > instead of Bars*. That will be more Java like behavior.
class Foo {
public:
Foo() {
bars[0] = new Bar;
bars[0]->id = 5;
}
~Foo() { freeBarsMemory(); }
struct Bar {
int id;
};
typedef std::map<int,Bar*> BarsList;
void set_bars(const BarsList& b) {
freeBarsMemory();
bars = b;
}
void hello() {
std::cout << bars[0]->id << std::endl;
}
protected:
BarsList bars;
void freeBarsMemory()
{
BarsList::const_iterator it = bars.begin();
BarsList::const_iterator end = bars.end();
for (; it != end; ++it)
delete it->second;
bars.clear();
}
};
I'm not new to programming, but after working in Java I'm coming back to C++ and am a little confused about class variables that aren't pointers.
The confusion appears to come from a combination of data that is on the heap and data that is not necessarily on the heap. This is a common cause of confusion.
In the code you posted, bars is not a pointer. Since it's in class scope, it will exist until the object containing it (testbars) is destroyed. In this case testbars was created on the stack so it will be destroyed when it falls out of scope, regardless of how deeply nested that scope is. And when testbars is destroyed, subobjects of testbars (whether they are parent classes or objects contained within the testbars object) will have their destructors run at that exact moment in a well-defined order.
This is an extremely powerful aspect of C++. Imagine a class with a 10-line constructor that opens a network connection, allocates memory on the heap, and writes data to a file. Imagine that the class's destructor undoes all of that (closes the network connection, deallocates the memory on the heap, closes the file, etc.). Now imagine that creating an object of this class fails halfway through the constructor (say, the network connection is down). How can the program know which lines of the destructor will undo the parts of the constructor that succeeded? There is no general way to know this, so the destructor of that object is not run.
Now imagine a class that contains ten objects, and the constructor for each of those objects does one thing that must be rolled back (opens a network connection, allocates memory on the heap, writes data to a file, etc.) and the destructor for each of those objects includes the code necessary to roll back the action (closes the network connection, deallocates objects, closes the file, etc.). If only five objects are successfully created then only those five need to be destroyed, and their destructors will run at that exact moment in time.
If testbars had been created on the heap (via new) then it would only be destroyed when calling delete. In general it's much easier to use objects on the stack unless there is some reason for the object to outlast the scope it was created in.
Which brings me to Foo::bar. Foo::bars is a map that refers to objects on the heap. Well, it refers to pointers that, in this code example, refer to objects allocated on the heap (pointers can also refer to objects allocated on the stack). In the example you posted the objects these pointers refer to are never deleted, and because these objects are on the heap you're getting a (small) memory leak (which the operating system cleans up on program exit). According to the STL, std::maps like Foo::bar do not delete pointers they refer to when they are destroyed. Boost has a few solutions to this problem. In your case it's probably be easiest to simply not allocate these objects on the heap:
#include <iostream>
#include <map>
using std::map;
using std::cout;
class Foo {
public:
Foo() {
// normally you wouldn't use the parenthesis on the next line
// but we're creating an object without a name, so we need them
bars[0] = Bar();
bars[0].id = 5;
}
~Foo() { }
struct Bar {
int id;
};
void set_bars(map<int,Bar>& b) {
bars = b;
}
void hello() {
cout << bars[0].id << endl;
}
protected:
map<int,Bar> bars;
};
int main() {
Foo foo;
foo.hello();
map<int,Foo::Bar> testbars;
// create another nameless object
testbars[0] = Foo::Bar();
testbars[0].id = 10;
foo.set_bars(testbars);
foo.hello();
return 0;
}