How to initialize non-POD data in malloc memory - c++

I have a structure which has an std::list as its data member. That std::list is an collection of std::pair.
Like this(Inside .h file)
extern struct_info tt;
typedef struct_s *struct_info;
typedef
struct struct_s {
std::list < std::pair <char*, int> > names;
};
I am allocating memory for this structure in my .cpp file as:
tt = mem_malloc(sizeof(struct_t));
mem_malloc is my own memory allocating routine. Please note that it is already made extern in .h file.
Later, when I try to push_back any element into the list with following code:
std::pair <char*, int> myPair = std:make_pair("A", 5);
(tt->names).push_back(myPair);
It crashes while doing push_back. I do not know what is happening here. Do I need to call any constructor or initializer for the list in struct_s constructor?
What do you guys think?

You can't just allocate memory with size sizeof(struct_t) and expect to be able to use that memory as if a struct_t instance existed there - you need to construct it first. E.g.
tt = mem_malloc(sizeof(struct_t));
new (tt) struct_s{}; // <- "placement `new`"
// use `tt`...
tt->~struct_s(); // <- explicit destructor call
// deallocate tt
This is however a terrible idea, especially if done manually. The Standard Library provides allocator support - you should create an allocator that can be seamlessly used with the Standard Library instead.

You can also do:
struct_s obj;
*tt = obj;
.
.
.
free(tt);
After experiments:
1. With non POD types my suggested solution will (must) not work.
2. For non POD types if above copy mechanism is applied, it will start accessing uninitialised memory location (in copy-to-location), assuming as if those are well-formed objects, and therefore will cause segmentation fault.
3. Point 2 makes it compulsory to initialize such malloced memory for non-POD types data properly. This in C is not possible and we will also not encounter such scenario there as there is everything is POD. This is the reason (I think, one of the reasons) C++ struct is made very similar to Class, so that, as suggested in other solutions, we can make appropriate initialization calls (i.e. constructors).
So the solution is to use placement new operator as suggested by others.

Related

How can I pass and store an array of variable size containing pointers to objects?

For my project I need to store pointers to objects of type ComplicatedClass in an array. This array is stored in a class Storage along with other information I have omitted here.
Here's what I would like to do (which obviously doesn't work, but hopefully explains what I'm trying to achieve):
class ComplicatedClass
{
...
}
class Storage
{
public:
Storage(const size_t& numberOfObjects, const std::array<ComplicatedClass *, numberOfObjects>& objectArray)
: size(numberOfObjects),
objectArray(objectArray)
{}
...
public:
size_t size;
std::array<ComplicatedClass *, size> objectArray;
...
}
int main()
{
ComplicatedClass * object1 = new ComplicatedClass(...);
ComplicatedClass * object2 = new ComplicatedClass(...);
Storage myStorage(2, {object1, object2});
...
return 0;
}
What I am considering is:
Using std::vector instead of std::array. I would like to avoid this because there are parts of my program that are not allowed to allocate memory on the free-store. As far as I know, std::vector would have to do that. As a plus I would be able to ditch size.
Changing Storage to a class template. I would like to avoid this because then I have templates all over my code. This is not terrible but it would make classes that use Storage much less readable, because they would also have to have templated functions.
Are there any other options that I am missing?
How can I pass and store an array of variable size containing pointers to objects?
By creating the objects dynamically. Most convenient solution is to use std::vector.
size_t size;
std::array<ComplicatedClass *, size> objectArray;
This cannot work. Template arguments must be compile time constant. Non-static member variables are not compile time constant.
I would like to avoid this because there are parts of my program that are not allowed to allocate memory on the free-store. As far as I know, std::vector would have to do that.
std::vector would not necessarily require the use of free-store. Like all standard containers (besides std::array), std::vector accepts an allocator. If you implement a custom allocator that doesn't use free-store, then your requirement can be satisfied.
Alternatively, even if you do use the default allocator, you could write your program in such way that elements are inserted into the vector only in parts of your program that are allowed to allocate from the free-store.
I thought C++ had "free-store" instead of heap, does it not?
Those are just different words for the same thing. "Free store" is the term used in C++. It's often informally called "heap memory" since "heap" is a data structure that is sometimes used to implement it.
Beginning with C++11 std::vector has the data() method to access the underlying array the vector is using for storage.
And in most cases a std::vector can be used similar to an array allowing you to take advantage of the size adjusting container qualities of std::vector when you need them or using it as an array when you need that. See https://stackoverflow.com/a/261607/1466970
Finally, you are aware that you can use vectors in place of arrays,
right? Even when a function expects c-style arrays you can use
vectors:
vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");

Controlling memory with std::vector<T*>

Suppose that T contains an array whose size may vary depending on initialization. I'm passing a pointer to the vector to avoid copying all the data, and initialize as follows:
for(int i=10; i < 100; i++)
std::vector.push_back(new T(i));
On exiting, one deletes the element's of the vector. Is there a risk of memory loss if the data contained in T is also a pointer, even if there are good destructors? Eg
template<class M> class T{
M * Array;
public:
T(int i) : Array(new M[i]){ }
~T(){ delete Array;}
};
There are two major problems with your class T:
You use delete rather than delete [] to delete the array, giving undefined behaviour
You don't implement (or delete) the copy constructor and copy-assignment operator (per the Rule of Three), so there's a danger of two objects both trying to delete the same array.
Both of these can be solved easily by using std::vector rather than writing your own version of it.
Finally, unless you have a good reason (such as polymorphism) to store pointers, use std::vector<T> so that you don't need to manually delete the elements. It's easy to forget to do this when removing an element or leaving the vector's scope, especially when an exception is thrown. (If you do need pointers, consider unique_ptr to delete the objects automatically).
The answer is: don't.
Either use
std::vector<std::vector<M>> v;
v.emplace_back(std::vector<M>(42)); // vector of 42 elements
or (yuck)
std::vector<std::unique_ptr<M[]>> v;
// C++11
std::unique_ptr<M[]> temp = new M[42]; // array of 42 elements
v.emplace_back(temp);
// C++14 or with handrolled make_unique
v.emplace_back(std::make_unique<M[]>(42);
which both do everything for you with minimal overhead (especially the last one).
Note that calling emplace_back with a new argument is not quite as exception-safe as you would want, even when the resulting element will be a smart pointer. To make it so, you need to use std::make_unique, which is in C++14. Various implementations exist, and it needs nothing special. It was just omitted from C++11, and will be added to C++14.

C++ New vs Malloc for dynamic memory array of Objects

I have a class Bullet that takes several arguments for its construction. However, I am using a dynamic memory array to store them. I am using C++ so i want to conform to it's standard by using the new operator to allocate the memory. The problem is that the new operator is asking for the constructor arguments when I'm allocating the array, which I don't have at that time. I can accomplish this using malloc to get the right size then fill in form there, but that's not what i want to use :) any ideas?
pBulletArray = (Bullet*) malloc(iBulletArraySize * sizeof(Bullet)); // Works
pBulletArray = new Bullet[iBulletArraySize]; // Requires constructor arguments
Thanks.
You can't.
And if you truly want to conform to C++ standards, you should use std::vector.
FYI, it would probably be even more expensive than what you're trying to achieve. If you could do this, new would call a constructor. But since you'll modify the object later on anyway, the initial construction is useless.
1) std::vector
A std::vector really is the proper C++ way to do this.
std::vector<Bullet> bullets;
bullets.reserve(10); // allocate memory for bullets without constructing any
bullets.push_back(Bullet(10.2,"Bang")); // put a Bullet in the vector.
bullets.emplace_back(10.2,"Bang"); // (C++11 only) construct a Bullet in the vector without copying.
2) new [] operator
It is also possible to do this with new, but you really shouldn't. Manually managing resources with new/delete is an advanced task, similar to template meta-programming in that it's best left to library builders, who'll use these features to build efficient, high level libraries for you. In fact to do this correctly you'll basically be implementing the internals of std::vector.
When you use the new operator to allocate an array, every element in the array is default initialized. Your code could work if you added a default constructor to Bullet:
class Bullet {
public:
Bullet() {} // default constructor
Bullet(double,std::string const &) {}
};
std::unique_ptr<Bullet[]> b = new Bullet[10]; // default construct 10 bullets
Then, when you have the real data for a Bullet you can assign it to one of the elements of the array:
b[3] = Bullet(20.3,"Bang");
Note the use of unique_ptr to ensure that proper clean-up occurs, and that it's exception safe. Doing these things manually is difficult and error prone.
3) operator new
The new operator initializes its objects in addition to allocating space for them. If you want to simply allocate space, you can use operator new.
std::unique_ptr<Bullet,void(*)(Bullet*)> bullets(
static_cast<Bullet*>(::operator new(10 * sizeof(Bullet))),
[](Bullet *b){::operator delete(b);});
(Note that the unique_ptr ensures that the storage will be deallocated but no more. Specifically, if we construct any objects in this storage we have to manually destruct them and do so in an exception safe way.)
bullets now points to storage sufficient for an array of Bullets. You can construct an array in this storage:
new (bullets.get()) Bullet[10];
However the array construction again uses default initialization for each element, which we're trying to avoid.
AFAIK C++ doesn't specify any well defined method of constructing an array without constructing the elements. I imagine this is largely because doing so would be a no-op for most (all?) C++ implementations. So while the following is technically undefined, in practice it's pretty well defined.
bool constructed[10] = {}; // a place to mark which elements are constructed
// construct some elements of the array
for(int i=0;i<10;i+=2) {
try {
// pretend bullets points to the first element of a valid array. Otherwise 'bullets.get()+i' is undefined
new (bullets.get()+i) Bullet(10.2,"Bang");
constructed = true;
} catch(...) {}
}
That will construct elements of the array without using the default constructor. You don't have to construct every element, just the ones you want to use. However when destroying the elements you have to remember to destroy only the elements that were constructed.
// destruct the elements of the array that we constructed before
for(int i=0;i<10;++i) {
if(constructed[i]) {
bullets[i].~Bullet();
}
}
// unique_ptr destructor will take care of deallocating the storage
The above is a pretty simple case. Making non-trivial uses of this method exception safe without wrapping it all up in a class is more difficult. Wrapping it up in a class basically amounts to implementing std::vector.
4) std::vector
So just use std::vector.
It's possible to do what you want -- search for "operator new" if you really want to know how. But it's almost certainly a bad idea. Instead, use std::vector, which will take care of all the annoying details for you. You can use std::vector::reserve to allocate all the memory you'll use ahead of time.
Bullet** pBulletArray = new Bullet*[iBulletArraySize];
Then populate pBulletArray:
for(int i = 0; i < iBulletArraySize; i++)
{
pBulletArray[i] = new Bullet(arg0, arg1);
}
Just don't forget to free the memory using delete afterwards.
The way C++ new normally works is allocating the memory for the class instance and then calling the constructor for that instance. You basically have already allocated the memory for your instances.
You can call only the constructor for the first instance like this:
new((void*)pBulletArray) Bullet(int foo);
Calling the constructor of the second one would look like this (and so on)
new((void*)pBulletArray+1) Bullet(int bar);
if the Bullet constructor takes an int.
If what you're really after here is just fast allocation/deallocation, then you should look into "memory pools." I'd recommend using boost's implementation, rather than trying to roll your own. In particular, you would probably want to use an "object_pool".

How can I emulate a recursive type definition in C++?

Yesterday I asked the following question, reproduced here for convenience;
"For one of my projects, what I really wanted to do was this (simplifying it to the bare minimum);
struct Move
{
int src;
int dst;
};
struct MoveTree
{
Move move;
std::vector<MoveTree> variation;
};
I must admit that I assumed that it wouldn't be possible to do this directly, I thought a vector of MoveTree s within a MoveTree would be verboten. But I tried it anyway, and it works beautifully. I am using Microsoft Visual Studio 2010 Express.
Is this portable ? Is it good practice ? Do I have anything to worry about ?"
Basically the answer from the community was no, I couldn't do this, the standard forbids it, so the fact that it works means I am just getting lucky.
So my new question is. How can I implement the simple functionality I want in legal C++, without adding a whole heap of nasty complexity and pain ?
You'll need to use pointers, and dynamic allocation. And you should use smart pointers, to ensure you don't leak anything. boost::shared_ptr allows the type to be incomplete, and therefore this is legal:
std::vector< boost::shared_ptr<MoveTree> > variation;
(I don't know about 0x std::shared_ptr TBH, but it should be the same).
You may use Boost Pointer Container Library. It similar to using std::vector, but the container owns the pointer, so it will destroy the objects.
You may declare it:
#include <boost/ptr_container/ptr_vector.hpp>
struct MoveTree{
Move move;
boost::ptr_vector<MoveTree> variation;
};
Now, if you want to add a new element, you may use:
variation.push_back(new MoveTree());
Now, the container owns the pointer and you get it by reference, for example:
variation[i].move.src = ...
The object is destroyed when the container is destroyed.
I don't have a copy of the C++ standard on-hand, so I can't check the standard, but here's the problem:
Classes cannot contain concrete instances of themselves, even transitively - eg, struct foo { foo x; } is illegal, for obvious reasons. More generally, you cannot reference the size of the structure in any of its members, except the body of member functions.
Classes can contain pointers to themselves - struct foo { foo *x; } is perfectly fine
So the question is, does std::vector define any members (other than member functions) which directly or indirectly depend on sizeof(MoveTree)?
Obviously, std::vector cannot have a static member that is MoveTree itself, as this would imply that an empty vector invokes the MoveTree constructor. However one could envision a std::vector with an aligned char inlineStorage[sizeof(MoveTree)] optimization for one-element vectors. Leaving aside whether this would improve performance, the question at hand is if the standard allows the implementation to take this sort of approach.
That said, it's still a bad idea for a different reason: Because vectors have to copy their elements when resizing their storage, it's a bad idea to have elements with an expensive copy constructor in a vector. Here we have a class whose copy constructor has to recursively recreate the entire tree. It would be better to use a smart pointer class to indirectly reference the child nodes to avoid this overhead:
std::vector<boost::shared_ptr<MoveTree> > variation;
// in C++0x:
std::vector<std::shared_ptr<MoveTree> > variation;
// in C++0x you can also use for lower overhead:
std::vector<std::unique_ptr<MoveTree> > variation;
// you must then use this pattern to push:
variation.push_back(std::move(std::unique_ptr<MoveTree>(new MoveTree())));
If you can use the incomplete type MoveTree as a template parameter in any template, then use one of the solutions in the other answers (e.g. Cat Plus Plus's), or simply use your original solution, add some heavy comments, and do your penance later.
If you can't use it as any template parameter while it is still incomplete, you could use the pimpl idiom to work around this.
By the time the implementation class is defined, the MoveTree class will be complete:
struct Move
{
int src;
int dst;
};
struct MoveTreeImpl;
struct MoveTree
{
Move move;
// Todo: Implement RAII here for the impl
// Todo: Provide impl accessor functions here
private:
MoveTreeImpl* impl;
};
struct MoveTreeImpl
{
std::vector<MoveTree> variation;
};
There are hairy parts to this solution:
Since you're trying to avoid direct instantiation of any template with incomplete types, you'll have to implement RAII manually. You won't get help from std::scoped_ptr<MoveTreeImpl>, as MoveTreeImpl is also incomplete.
What signature do your accessor functions have? Can you return a std::vector<MoveTree>& from an accessor? I'm not sure on this - we're trying to avoid templates that use MoveTree directly. This might be different, because it is not a data member, but I'm not sure :)
Edit:
Reading a bit more, and getting responses from other users, it seems much of this nonsense is unnecessary. It is only the standard containers that have the restriction. You could implement the pimpl with a std:scoped_ptr<MoveTreeImpl>, and I think return std::vector<MoveTree>& from an accessor function, both with no problems.
Use a pointer (or smart pointer) to the type in the Vector, this will be portable. This is because a pointer to a type is complete by just it declaration you don't need the definition.
struct Move
{
int src;
int dst;
};
struct MoveTree;
struct MoveTree
{
Move move;
std::vector<MoveTree*> variation;
};
If you require the type to be managed then use a smart pointer that can handle the delete for you.
Original answer to this question.

c++ string in C struct, is it illegal?

struct run_male_walker_struct {
string male_user_name;
string show_name;
};
typedef struct run_male_walker_struct run_male_walker_struct_t;
in another function:
run_male_walker_struct_t *p = malloc(sizeof(struct run_male_walker_struct));
question, is it illegal? As the string is a class, it's size can't be determined by sizeof().
This is illegal, but not for the reasons you're thinking.
The difference between std::malloc()/std::free() and new/delete is that the latter will call constructors/destructors, while the former won't. The expression
void* p = std::malloc(sizeof(run_male_walker_struct))
will return a blob of uninitialized memory on which no constructor is called. You shouldn't touch it with a ten foot pole - except for invoking a constructor on it:
run_male_walker_struct* pw = new(p) run_male_walker_struct;
If you do this, you will have to do the reverse, too:
pw->~run_male_walker_struct();
before you free the memory:
std::free(p);
However, that leaves the question why you want to do that.
The only reason to do this should be when you want to separate memory allocation from construction (like, for example, in a pool allocator). But if you need that, it's best hidden behind some interface. A natural one would be overloading new and delete per class. Also, std::vector does this internally.
Not really sure what you're asking here... Just to be clear, the struct keyword is a valid C++ designation, that functions nearly identically to class except for the default privacy. So if you're compiling with g++, and including the string library, this is a valid statement.
However, calling with malloc() will just give you the memory, not actually construct the values inside that struct. You could more appropriately instantiate it by calling it's default constructor.
The struct definition itself is fine. It results is a non-POD aggregate. But you should prefer the use of new and delete over malloc and free because these handle construction and destruction properly. If you want to keep using malloc and free you have to use the placement-new to properly construct the object and invoke the destructor manually to destroy it before you free it:
#include <new>
...
run_male_walker_struct *p = (run_male_walker_struct*)
malloc(sizeof(run_male_walker_struct));
new(p) run_male_walker_struct; // <-- placement-new
...
p->~run_male_walker_struct(); // <-- pseudo destructor call
free(p);
Or simply:
run_male_walker_struct *p = new run_male_walker_struct;
...
delete p;
BTW: the typedef is not necessary in C++
Try not to use malloc, if you are in C++.
Using NEW is a better alternative, when you browse into the NEW() code, you will realize it does call malloc!!!
The pros of using NEW is it will call the constructor of your class instantiated.
Another minor comment, the code you provided should not be compilable:
run_male_walker_struct_t *p = malloc(sizeof(struct run_male_walker_struct));
Should be
run_male_walker_struct_t *p = (run_male_walker_struct_t*)malloc(sizeof(struct run_male_walker_struct));
this is due to malloc will return a void*.
Using malloc() would work, but using it will only create enough space for your struct.
This means that you will not be able to use your strings properly, because they weren't initialised with their constructors.
Note that string classes don't have their contents in stack memory, but in dynamic memory, which doesn't affect the size of the struct. All classes and structs have a static size, that are known at compile-time (if the struct/class was defined).
I would suggest using new. Using malloc will stuff up the strings.
This raises a question of my own, how did constructors get called on dynamically allocated instantiation in C (were there no such things as constructors in C?). If so, yet another reason against using pure C.
How about
run_male_walker_struct_t * p = new run_male_walker_struct_t:
I'm fairly sure this is legal because the size of the std::string object will be known even if the lengths of the strings are not known. The results may not be what you expect though because malloc won't call constructors.
Try this:
std::string testString1("babab");
std::string testString2("12345678");
std::string testString3;
std::cout <<" sizeof(testString1)" <<sizeof(testString1) << std::endl;
std::cout <<" sizeof(testString2)" <<sizeof(testString2) << std::endl;
std::cout <<" sizeof(testString3)" <<sizeof(testString3) << std::endl;
On my machine this gives me the following output:
sizeof(testString1)8
sizeof(testString2)8
sizeof(testString3)8
Also is there some reason you are not using:
run_male_walker_struct_t *p = new(struct run_male_walker_struct);
This is the correct way to do it in c++, using malloc is almost certainly a mistake.
EDIT: see this page for a more detailed explanation of new vs malloc in c++:
http://www.codeproject.com/KB/tips/newandmalloc.aspx
The answer depends on what you mean by a "C struct".
If you mean "a struct that is valid under the C language", then the answer is obviously: it contains a datatype that isn't valid C, and so the struct itself isn't valid either.
If you mean a C++ POD type, then the answer is no, it is not illegal, but the struct is no longer a POD type (because in order to be POD, all its members must be POD as well, and std::string isn't)