Is there a c++ counterpart to posix_memalign? - c++

When I call posix_memalign to allocate aligned memory for an object of type Foo in my C++ code, I am required to do a reinterpret_cast of the address of that pointer to void**.
In general when I encounter this situation, it implies that I am missing some language feature. That is, it feels like I am calling malloc in c++ when I should be calling new.
,
Is there a type-aware new equivalent for aligned memory allocation in c++?

I will start with the core advice first.
Foo* aligned_foo() {
void* raw = 0;
if(posix_memalign(&raw, 8, sizeof(Foo)))
return 0; // we could throw or somehow communicate the failure instead
try{
return new(raw) Foo();
}catch(...){
free(raw);
throw;
}
}
then when you are done with the Foo* foo, do a foo->~Foo(); free(foo); instead of delete.
Note the lack of reinterpret_casts.
Here is an attempt to make it generic:
// note: stateless. Deleting a derived with a base without virtual ~base a bad idea:
template<class T>
struct free_then_delete {
void operator()(T*t)const{
if(!t)return;
t->~T();
free(t);
};
};
template<class T>
using aligned_ptr=std::unique_ptr<T,free_then_delete<T>>;
// the raw version. Dangerous, because the `T*` requires special deletion:
template<class T,class...Args>
T* make_aligned_raw_ptr(size_t alignment, Args&&...args) {
void* raw = 0;
if(int err = posix_memalign(&raw, alignment, sizeof(T)))
{
if (err==ENOMEM)
throw std::bad_alloc{};
return 0; // other possibility is bad alignment: not an exception, just an error
}
try {
// returns a T*
return new(raw) T(std::forward<Args>(args)...);
} catch(...) { // the constructor threw, so clean up the memory:
free(raw);
throw;
}
}
template<class T,class...Args> // ,class... Args optional
aligned_ptr<T> make_aligned_ptr(size_t alignment=8, Args&&...args){
T* t = make_aligned_raw_ptr<T>(alignment, std::forward<Args>(args)...);
if (t)
return aligned_ptr<T>(t);
else
return nullptr;
}
The unique_ptr alias aligned_ptr bundles the destroyer along with the pointer -- as this data requires destruction and free, not delete, this makes it clear. You can still .release() the pointer out, but you still have to do the steps.

Actually, you don't want to do a reinterpret_cast because then your Foo constructor isn't called. If you need to allocate memory from a special place, you then call placement new to construct the object in that memory:
void* alloc;
posix_memalign(&alloc, 8, sizeof(Foo));
Foo* foo = new (foo) Foo();
The only other way (pre C++11) would be overriding the new operator for your class. That works if you have a particular class that always requires this special allocation:
class Foo {
void* operator new(size_t size) {
void* newobj;
posix_memalign(&newobj, 8, sizeof(Foo));
return newobj;
}
};
Then anytime you call new Foo() it will invoke this allocator. See http://en.cppreference.com/w/cpp/memory/new/operator_new for more information. Overriding operator new and operator delete can be done for individual classes or globally.

C++11 has added native language support for alignment declarations and aligned allocation.
You can specify alignas(N) on your type in C++11 to specify the minimum alignment for new objects, which the default new will respect.
Example from cppreference:
struct alignas(16) sse_t { // SSE-safe struct aligned on 16-byte boundaries
float v[4];
};
then you can simply do
sse_t *ssevec = new sse_t;
For a replacement for posix_memalign, you can use std::aligned_storage<sizeof(T), N>, also in C++11.

Related

What should I do if the 2nd malloc failed in the same constructor

Note that the basis of the question is to use two malloc()s...while suggesting not using malloc() at all is perfectly valid and leads to better design, this is not the point of the question. Perhaps you can think that my client is a psychopath and I am paid to have two malloc()s.
===== Here comes the question itself =====
Say I am stuck with the following class and cannot switch to features such as vector<int>, unique_ptr<int>, etc, while not "modern", it should still work without leaking any memory, whether or not malloc() succeeds:
class Foo {
private:
int *ptr;
public:
Foo () {
this->ptr = (int*)malloc(sizeof(int) * ARR_SIZE);
if (this->ptr == NULL) {
std::bad_alloc exception;
throw exception;
}
}
~Foo () {
free(this->ptr);
}
};
The question appears if I need to malloc() twice within the same constructor:
class Foo {
private:
int *ptr0;
int *ptr1;
public:
Foo () {
this->ptr0 = (int*)malloc(sizeof(int) * ARR_SIZE_0);
if (this->ptr0 == NULL) {
std::bad_alloc exception;
throw exception;
}
this->ptr1= (int*)malloc(sizeof(int) * ARR_SIZE_1);
if (this->ptr1== NULL) {
free(this->ptr0); // QUESTION: Is this needed and does it follow the best practice?
std::bad_alloc exception;
throw exception;
}
}
~Foo () {
free(this->ptr0);
free(this->ptr1);
}
};
I am aware that it could be more advisable in the 2nd case that we create two classes which wrap one pointer each, so the principle of RAII can be thoroughly followed and the above kind of "C-style" free() in constructor is not needed.
The question is, say, for whatever reason, I must have two malloc()s in the constructor, is my design good enough (i.e., not leaking memory and not too verbose)?
Here is a RAII-enabled version.
struct Free
{
void operator()(void* p) const { std::free(p); }
};
template <typename T, typename Deleter = Free>
std::unique_ptr<T, Deleter> raii_malloc()
{
T* obj = static_cast<T*>(std::malloc(sizeof(T)));
if (obj == nullptr) throw std::bad_alloc();
return std::unique_ptr<T, Deleter>(obj);
}
template <typename T, typename Deleter = Free>
std::unique_ptr<T[], Deleter> raii_malloc_array(size_t size)
{
T* obj = static_cast<T*>(std::malloc(sizeof(T) * size));
if (obj == nullptr) throw std::bad_alloc();
return std::unique_ptr<T[], Deleter>(obj);
}
template <typename T>
using fptr = std::unique_ptr<T, Free>;
Now your class looks like this:
class Foo
{
fptr<int[]> ptr0;
fptr<int[]> ptr1;
public:
Foo() : ptr0{raii_malloc_array<int>(ARR_SIZE_0)},
ptr1{raii_malloc_array<int>(ARR_SIZE_1)}
{}
// no destructor needed
};
Note that this version is non-copyable. If you need copying, add a custom copy constructor and/or assignment operator (still no destructor needed).
You can use this with C objects that contain internal pointers or other resources that need to be freed, you just need to supply a different deleter instead of Free.
If unique_ptr is not available, it is extremely easy to roll your own simplified version.
Use std::vector or std::unique_ptr to help manage memory.
Don't use malloc unless you must.
Make sure your class is either safe to copy/move, or not copyable/movable (i.e., deleted constructor, operator=).
Think about how likely you are to handle an out-of-memory case anyway (are you going to open a file and log it while you're out of system memory?), and perhaps just terminate if the allocation fails.
A rather simple way to avoid the issue would be to allocate the necessary memory for your member variables in one go.
class Foo
{
public:
Foo()
{
ptr0 = new int[ARR_SIZE0 + ARR_SIZE1];
ptr1 = ptr0 + ARR_SIZE0;
}
~Foo()
{
delete ptr0[];
}
// PLEASE insert the rest of the
// necessary constructors
// and assignment operators...
private:
int * ptr0;
int * ptr1;
};
Using new instead of malloc here because, if you have to do manual allocations, at least do them using the C++ construct.
Your updated question makes it clearer what the question is about. I feel my first answer still holds value, but this one goes in another direction entirely, which is why I wrote it as a separate answer.
It boils down to:
If I am about to throw an exception from a constructor, do I have to actively release resources previously allocated manually in that constructor?
Yes, you do, for any resources that you would likewise have to free / close / disconnect / ... in the destructor.
If a constructor fails (i.e., throws), the object is not constructed. It is, therefore, not destructed either -- its destructor will never be called. You would lose access to ptr0 and ptr1. Your exception might be caught, the program might continue -- but you would have leaked the memory.
So, again, yes, please do release any resource you would release in the destructor that you already allocated in the constructor before throwing the exception.
All the other comments and remarks also hold true, though. You should strive not to mix C constructs and C++ constructs. Writing idiomatic C++ instead of what is disparagingly called "C with classes" will result in better readable, more stable and likely more efficient code.

Type information in placement new

I have a placement new operator that, quite predictably, allocates memory from a pool. However, I also need to know the object type to set up some meta fields. I could pass it as a second argument to placement new as a string, but since I specify the type when calling new anyway, isn't there any way to get it implicitly?
E.g. I could do this:
void* operator new(size_t count, Pool* pool, const char* type)
{
return pool->alloc(count, type); // type is used to associate metadata with the allocated chunk
}
Car* car = new(pool, "Car") Car(...);
But can't I do something like this?
template<class T>
void* operator new(size_t count, Pool* pool)
{
return pool->alloc(count, typeid(T).name());
}
Car* car = new(pool) Car(...);
No, sorry. Except for member allocator functions, which only work for class types you control, C++ neither uses the class type to select an operator new function nor provides any standard way for an operator new function to determine the type of the calling new-expression (if any).
You could give your Pool class a template member function to take care of both allocating and constructing:
template<typename T, typename... Args>
T* Pool::create(Args&& ... args) {
void* ptr = alloc(count, typeid(T).name());
try {
return ::new(ptr) T(std::forward<Args>(args)...);
} catch (...) {
dealloc(ptr);
throw;
}
}
// ...
Car* car = pool->create<Car>(vroom);
(Other comments about stuff you might already know: Remember to implement a matching placement-delete in case a class constructor throws an exception. Consider making an Allocator interface for compatibility with the standard library.)

Determine if an object is dynamically allocated or not in C++

I have a simple C++ class for which I need to know whether an object should be delete'd or not at a certain point in my program. The mechanism should be portable across platforms and modern C++ compilers.
One way of doing it I can think of is: have a member field which is not initialized by the constructor but instead is assigned by the overloaded operator new, like so:
class message
{
protected:
int id;
bool dynamic;
public:
message(int _id): id(_id)
{
// don't touch `dynamic` in the constructor
}
void* operator new(size_t size)
{
message* m = (message*)::operator new(size);
m->dynamic = true;
return m;
}
void operator delete(void* m)
{
if (((message*)m)->dynamic)
::operator delete(m);
}
};
Apart form that it "feels" wrong, what is wrong with this method?
Edit: should have mentioned that the object is either dynamic or static (and never stack-local) and thus is guaranteed to be either zeroed or initialized with new.
The constructor needs to set dynamic to false, and then instead of overriding new, you need a static method like:
static message *createMessage(int _id)
{
message *ret = new message(_id);
ret->dynamic = true;
return ret;
}
And then call that method instead of newing a message.
Don’t do this. Apart from the fact that it won’t work, an object shouldn’t be managing anything about its own lifetime. You can use a unique_ptr or shared_ptr with a custom deleter, and if the object is stack-allocated, you know at its allocation site; in that case, you can supply a no-op deleter such as the following:
struct null_deleter {
template<class T>
void operator()(const T*) const {}
};

Copy data from a pointer or chain of pointers (Object pointer, templates)

How the push_back of stl::vector is implemented so it can make copy of any datatype .. may be pointer, double pointer and so on ...
I'm implementing a template class having a function push_back almost similar to vector. Within this method a copy of argument should be inserted in internal allocated memory.
In case the argument is a pointer or a chain of pointers (an object pointer); the copy should be made of actual data pointed. [updated as per comment]
Can you pls tell how to create copy from pointer. so that if i delete the pointer in caller still the copy exists in my template class?
Code base is as follows:
template<typename T>
class Vector
{
public:
void push_back(const T& val_in)
{
T a (val_in); // It copies pointer, NOT data.
m_pData[SIZE++] = a;
}
}
Caller:
// Initialize my custom Vector class.
Vector<MyClass*> v(3);
MyClass* a = new MyClass();
a->a = 0;
a->b = .5;
// push MyClass object pointer
// now push_back method should create a copy of data
// pointed by 'a' and insert it to internal allocated memory.
// 'a' can be a chain of pointers also.
// how to achieve this functionality?
v.push_back(a);
delete a;
I can simply use STL vector to accomplish the tasks but for experiment purposes i'm writing a template class which does exactly the same.
Thanks.
if you have polymorphic object ( the pointed object may be more specialized than the variable ), I suggest you creating a virtual method called clone() that allocate a new pointer with a copy of your object:
Base* A::clone() {
A* toReturn = new A();
//copy stuff
return toReturn;
}
If you can't modify your Base class, you can use RTTI, but I will not approach this solution in this answer. ( If you want more details in this solution, please make a question regarding polymorphic cloning with RTTI).
If you have not a polymorphic object, you may allocate a new object by calling the copy constructor.
void YourVector::push_back(Base* obj) {
Base* copy = new Base(obj);
}
But it smells that what you are really needing is shared_ptr, avaliable in <tr1/memory> ( or <memory> if you use C++0x ).
Update based on comments
You may also have a two template parameters list:
template <typename T>
struct CopyConstructorCloner {
T* operator()(const T& t) {
return new T(t);
}
}
template <typename T, typename CLONER=CopyConstructorCloner<T> >
class MyList {
CLONER cloneObj;
public:
// ...
void push_back(const T& t) {
T* newElement = cloneObj(t);
// save newElemenet somewhere, dont forget to delete it later
}
}
With this approach it is possible to define new cloning politics for things like pointers.
Still, I recommend you to use shared_ptrs.
I think for this kind of problems it is better to use smart pointers ex: boost::shared_ptr or any other equivalent implementation.
There is no need to call new for the given datatype T. The push_back implementation should (must) call the copy-constructor or the assignment operator. The memory should have been allocated to hold those elemnets that are being pushed. The intial memory allocation should not call CTOR of type T. Something like:
T* pArray;
pArray = (T*) new BYTE[sizeof(T) * INITIAL_SIZE);
And then just put new object into pArray, calling the assignment operator.
One solution is to make a copy construction:
MyClass *p = new MyClass();
MyVector<MyClass*> v;
v.push_back(new MyClass(*p));
Update: From you updated question, you can definitely override push_back
template<typename T>
class MyVector {
public:
void push_back (T obj); // general push_back
template<typename TYPE> // T can already be a pointer, so declare TYPE again
void push_back (TYPE *pFrom)
{
TYPE *pNew = new TYPE(*pFrom);
// use pNew in your logic...
}
};
Something like this:
template<typename T>
class MyVector
{
T* data; // Pointer to internal memory
size_t count; // Number of items of T stored in data
size_t allocated; // Total space that is available in data
// (available space is => allocated - count)
void push_back(std::auto_ptr<T> item) // Use auto pointer to indicate transfer of ownership
/*void push_back(T* item) The dangerous version of the interface */
{
if ((allocated - count) == 0)
{ reallocateSomeMemory();
}
T* dest = &data[count]; // location to store item
new (dest) T(*item); // Use placement new and copy constructor.
++count;
}
// All the other stuff you will need.
};
Edit based on comments:
To call it you need to do this:
MyVector<Plop> data;
std::auto_ptr<Plop> item(new Plop()); // ALWAYS put dynamically allocated objects
// into a smart pointer. Not doing this is bad
// practice.
data.push_back(item);
I use auto_ptr because RAW pointers are bad (ie in real C++ code (unlike C) you rarely see pointers, they are hidden inside smart pointers).

Which way to delete pointer: delete/delete[]/free?

I am implementing standart template tree structure, and I came across small problem.
Idea that each node will hold pointer to some data. Later in order to delete element correctly I need to know if its a single pointer or pointer to an array.
Inside of my tree->ReleaseMemory() method I have this code:
if (node->_data != NULL) {
switch (_destructionMethod){
case tree_delete:
delete node->_data; break;
case tree_deleteList:
delete [] node->_data; break;
case tree_free:
free(node->_data); break;
}
}
where _destructionMethod has been set during initialisation of the node.
Is there any way I can choose correct destructor without predefining it in special variable for it during initialisation ?
Thanks!
First basic:
delete is used when you allocate memory with new:
int *p = new int;
int *a = new int[10];
//...
delete p;
delete []a; //note the difference!
free is used when you allocate memory with malloc:
int *p = (int*)malloc(sizeof(int) * 1);
int *a = (int*)malloc(sizeof(int) * 10);
//...
free(p);
free(a); //no difference!
Now your problem:
Is there any way I can choose correct destructor without predefining it in special variable for it during initialisation
Consider policy-based design. That means, write allocator that will encapsulate allocation and deallocation in a class and use that consistently in your code.
No, there is no portable way to find out what allocator a particular pointer originally came from.
There's no way to interrogate a pointer to find out how it was allocated, but a common idiom is to give the allocated object itself responsibility for its own destruction. It looks like your object types are not all class types, though, so you would need to wrap them in order to do this. For example:
class destroyable_node
{
virtual void destroy() = 0;
};
template <typename T> class object_node : public destroyable_node
{
private:
T * value_;
public:
// Presumes T is copy-constructable.
object_node(T value) : value_( new T(value) ) {}
operator T&() {return value_;}
operator T const &() const {return value_;}
void destroy() {delete value_;}
};
template<typename T> class array_node : public destroyable_node
{
private:
T * value_;
public:
array_node(T[] value)
: value_( new T[ sizeof(value)/sizeof(T) ] )
{
std::copy(value, value + sizeof(value)/sizeof(T), value_);
}
operator T*() {return value_;}
operator T const *() const {return value_;}
void destroy() {delete[] value_;}
};
...and so on.
Don't do this at all. Use a smart pointer, like shared_ptr from C++0x or Boost or if that is not an option, auto_ptr from C++. If you could have more than one object, consider using std::vector.
Manual resource management is messy and difficult to get right.
Maybe a better design is to implement an abstract interface used by your container with three concrete subclasses that know what kind of thing they hold pointers to. Your container would simply call a destroy() method in the base class and let the derived classes worry about calling the correct destructor.