How do I properly overload new? - c++

My code is below. However before main() is run something simple such as a static std::string globalvar; will call new. Before MyPool mypool is initialized.
MyPool mypool;
void* operator new(size_t s) { return mypool.donew(s); }
Is there anyway I can force mypool to be initialized first? I have no idea how overloading new is suppose to work if there is no way to initialize its values so I am sure there is a solution to this.
I am using both visual studios 2010 and gcc (cross platform)

Make mypool a static variable of your operator new function:
void* operator new(size_t s) {
static MyPool mypool;
return mypool.donew(s);
}
It will be initialized upon first call of the function (i.e. the operator new).
EDIT: As the commenters pointed out, declaring the variable as static in the operator new functions limits its scope and makes it inaccessible in the operator delete. To fix that, you should make an accessor function for your pool object:
MyPool& GetMyPool() {
static MyPool mypool;
return mypool;
}
and invoke it in both operator new and operator delete:
void* operator new(size_t s) {
return GetMyPool().donew(s);
}
// similarly for delete
As before, declaring it as static local variable guarantees initialization upon first invocation of GetMyPool function. Additionally, it will be the same pool object in both operators which likely what you want.

Properly? Best don't. Try Boost.Pool, and just use their allocation mechanics. Or if you insist on using your pool, make a new allocation function. I've seen horrible things done to the operator new, and I'm feeling sorry for it. :(
IMHO, the only time you should overload new is when implementing a memory manager for observation of the allocs / deallocs. Otherwise, just write your own functions and use them instead. Or for most containers, you can give them allocators.

Global initialization occurs in three steps, zero initialization, static
initialization and dynamic initialization. In that order. If your
operator new uses non-local variables, these variables must depend on
only zero or static initialization; as you said, you cannot guarantee
that your operator new won't be called before any particular variable
with dynamic initialization will have occured.
If you need objects with dynamic initialization (often the case), there
are two ways of handling this:
declare a pointer to the object, rather than the object itself, and
in operator new, check if the pointer is null, and initialize it
there, or
call a function which returns a reference to a local instance.
Neither of these solutions is thread safe, but that's likely not a
problem. They are thread safe once the first call returns, so if
there is any invocation of new before threading starts, you're OK.
(It's something to keep in mind, however. If unsure, you can always
allocate and delete an object manually before the first thread is
started—perhaps in the initialization of a static object.)

Related

Constexpr alternative to placement new to be able to leave objects in memory uninitialized?

I am trying to create a static container which has stack based memory and can hold N instances of T. Much alike std::vector I want currently unused memory to not contain initialized items of T. This is usually solved with placement new but that's not possible to use in constexpr.
Using unions
I found a trick that you can use a union for this as follows:
template <typename value_type>
union container_storage_type
{
struct empty{};
constexpr container_storage_type(): uninitialized{}{}
constexpr container_storage_type(value_type v): value(v){}
constexpr void set(value_type v)
{
*this = literal_container_storage_type{v};
}
empty uninitialized;
value_type value;
};
This lets you store items uninitialized by setting the empty member and this works around the limitation that all members in constexpr have to be initialized.
Now the problem with this approach is that if value_typeis a type that implements operator=, the rule for unions says:
If a union contains a non-static data member with a non-trivial special member function (copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.
This means that to be able to use this trick, I need to implement operator= in the union too, but how would that look?
constexpr container_storage_type& operator=(const container_storage_type& other)
{
value = other.value; //ATTEMPT #1
//*this = container_storage_type(other.value);ATTEMPT #2
return *this;
}
Attempt #1: This does not seem possible as the compiler complains that changing the active member of a union is simply disallowed in constant expressions.
Attempt #2: This works in the set() method from the previous snippet, as it doesn't change the active member per se, but reassigns the whole union. This trick seems unable to be used in the assignment operator however since that causes endless recursion...
Am I missing something here, or is this truly a dead end for using unions as a placement-new alternative in constexpr?
Are there other alternatives to placement new that I have completely missed?
https://godbolt.org/z/km0nTY Code that illustrates the problem
In C++17, you can't.
The current restrictions on what you cannot do in constant expressions include:
an assignment expression ([expr.ass]) or invocation of an assignment operator ([class.copy.assign]) that would change the active member of a union;
a new-expression;
There really is no way around that.
In C++20, you will be able to, but probably not the way you think. The latter restriction is going to be relaxed in C++20 as a result of P0784 to something like:
a new-expression (8.3.4), unless the selected allocation function is a replaceable global allocation function (21.6.2.1, 21.6.2.2);
That is, new T will become fine but new (ptr) T will still not be allowed. As part of making std::vector constexpr-friendly, we need to be able to manage "raw" memory - but we still can't actually manage truly raw memory. Everything still has to be typed. Dealing with raw bytes is not going to work.
But std::allocator doesn't entirely deal in raw bytes. allocate(n) gives you a T* and construct takes a T* as a location and a bunch of arguments and creates a new object at that location. You may be wondering at this point how this is any different from placement new - and the only difference is that sticking with std::allocator, we stay in the land of T* - but placement new uses void*. That distinction turns out to be critical.
Unfortunately, this has the interesting consequence of your constexpr version "allocates" memory (but it allocates compiler memory, which will get elevated to static storage as necessary - so this does what you want) - but your pure runtime version surely does not want to allocate memory, indeed the whole point would be that it does not. To that end, you will have to use is_constant_evaluated() to switch between the allocating at constant evaluation time and non-allocating at runtime. This is admittedly not beautiful, but it should work.
Your storage can look something like this:
// For trivial objects
using data_t = const array<remove_const_t<T>, Capacity>>;
alignas(alignof(T)) data_t data_{};
// For non-trivial objects
alignas(alignof(T)) aligned_storage_t<T> data_[Capacity]{};
This will allow you to create a const array of non-const objects. Then constructing objects will look something like this:
// Not real code, for trivial objects
data_[idx] = T(forward<Args>(args)...);
// For non-trivial objects
new (end()) T(forward<Args>(args)...);
Placement new is mandatory here. You will be able to have the storage at compile-time, but you cannot construct it at compile-time for non-trivial objects.
You will also need to take into account whether or not your container is zero-sized, etc. I suggest you look at existing implementations for fixed sized vectors and there are even some proposals for constexpr fixed sized vectors like p0843r1.

Eliminate warning "construction of local static object is not thread-safe"

I have the following class:
struct globalAllocated
{
void operator delete(void*p)
{
static HANDLE heap= GetHeap();
::HeapFree(heap, 0, p);
}
}
warning C4640: 'heap' : construction of local static object is not thread-safe
I thought about using some synchronization with mutex but it seems costly.
Making the heap a private member won't work because the operator delete override must be static, so heap must be private- but if I declare it as a static class member, there is no where for me to initialize it.
What's the best solution?
If you can use C++11, it's required to be thread-safe there. (But that could easily be implemented by using a mutex as well, if you're concerned about performance issues.)
More generally: try to ensure that the function is called before multiple threads are started. (In many applications, all that is needed is to call it somewhere in the initialization of a static object.)

What is the lifecycle of a C++ object?

I'm a seasoned C developer who is just now getting into C++, and I must admit, I'm very confused about how many ways there are to create, retain, and destroy C++ objects. In C, life is simple: assignment with = copies on the stack, and malloc/free manage data on the heap. C++ is far from that, or so it seems to me.
In light of that, here are my questions:
What are all the ways to create a C++ object? Direct/copy constructor, assignment, etc. How do they work?
What are all the different initialization syntaxes associated with all these types of object creation? What's the difference between T f = x, T f(x);, T f{x};, etc.?
Most importantly, when is it correct to copy/assign/whatever = is in C++, and when do you want to use pointers? In C, I got very used to throwing pointers around a lot, because pointer assignment is cheap but struct copying is less so. How do C++'s copy semantics affect this?
Finally, what are all these things like shared_ptr, weak_ptr, etc.?
I'm sorry if this is a somewhat broad question, but I'm very confused about when to use what (not even mentioning my confusion about memory management in collections and the new operator), and I feel like everything I knew about C memory management breaks down in C++. Is that true, or is my mental model just wrong?
To sum things up: how are C++ objects created, initialized, and destroyed, and when should I use each method?
First of all, your memory management skills are useful in C++, just they are a level below the C++ way of doing things, but they are there...
About your questions, they are a bit broad, so I'll try to keep it short:
1) What are all the ways to create a C++ object?
Same as C: they can be global variables, local automatic, local static or dynamic. You may be confused by the constructor, but simply think that every time you create an object, a constructor is called. Always. Which constructor is simply a matter of what parameters are used when creating the object.
Assignment does not create a new object, it simply copies from one oject to another, (think of memcpy but smarter).
2) What are all the different initialization syntaxes associated with all these types of object creation? What's the difference between T f = x, T f(x);, T f{x};, etc.?
T f(x) is the classic way, it simply creates an object of type T using the constructor that takes x as argument.
T f{x} is the new C++11 unified syntax, as it can be used to initialize aggregate types (arrays and such), but other than that it is equivalent to the former.
T f = x it depends on whether x is of type T. If it is, then it equivalent to the former, but if it is of different type, then it is equivalent to T f = T(x). Not that it really matters, because the compiler is allowed to optimize away the extra copy (copy elision).
T(x). You forgot this one. A temporary object of type T is created (using the same constructor as above), it is used whereever it happens in the code, and at the end of the current full expression, it is destroyed.
T f. This creates a value of type T using the default constructor, if available. That is simply a constructor that takes no parameters.
T f{}. Default contructed, but with the new unified syntax. Note that T f() is not an object of type T, but instead a function returning T!.
T(). A temporary object using the default constructor.
3) Most importantly, when is it correct to copy/assign/whatever = is in C++, and when do you want to use pointers?
You can use the same as in C. Think of the copy/assignment as if it where a memcpy. You can also pass references around, but you also may wait a while until you feel comfortable with those. What you should do, is: do not use pointers as auxiliary local variables, use references instead.
4) Finally, what are all these things like shared_ptr, weak_ptr, etc.?
They are tools in your C++ tool belt. You will have to learn through experience and some mistakes...
shared_ptr use when the ownership of the object is shared.
unique_ptr use when the ownership of the object is unique and unambiguous.
weak_ptr used to break loops in trees of shared_ptr. They are not detected automatically.
vector. Don't forget this one! Use it to create dynamic arrays of anything.
PS: You forgot to ask about destructors. IMO, destructors are what gives C++ its personality, so be sure to use a lot of them!
This is a fairly broad question, but I'll give you a starting point.
What's known in C as a "stack variable" is also called an object with "automatic storage". The lifetime of an object with automatic storage is fairly easy to understand: it's created when control reaches the point it's defined, and then destroyed when it goes out of scope:
int main() {
int foo = 5; // creation of automatic storage
do_stuff();
foo = 1;
// end of function; foo is destroyed.
}
Now, a thing to note is that = 5 is considered part of the initialization syntax, while = 1 is considered an assignment operation. I don't want you to get confused by = being used for two different things in the language's grammar.
Anyway, C++ takes automatic storage a bit further and allows arbitrary code to be run during the creation and destruction of that object: the constructors and destructors. This gives rise to the wonderful idiom called RAII, which you should use whenever possible. With RAII, resource management becomes automatic.
what are all these things like shared_ptr, weak_ptr, etc.?
Good examples of RAII. They allow you to treat a dynamic resource (malloc/free calls) as an automatic storage object!
Most importantly, when is it correct to copy/assign/whatever = is in C++, and when do you want to use pointers? In C, I got very used to throwing pointers around a lot, because pointer assignment is cheap but struct copying is less so. How do C++'s copy semantics affect this?
const references everywhere, especially for function parameters. const refs avoid copies and prevent modification of the object. If you can't use const ref, chances are a normal reference is suitable. If for some reason you want to reset the reference or set it to null, use a pointer.
What are all the ways to create a C++ object? Direct/copy constructor, assignment, etc. How do they work?
In short, all constructors create objects. Assignment doesn't. Read a book for this.
There are many ways of implicit object creating in C++ apart from explicit ones. Almost all of them use copy-constructor of the object's class. Remember: Implicit copying may require the copy constructor and/or assignment operator of a T type to be declared in public scope depending on where copying occurs. So in course:
a) explicit creation of a brand new object in stack:
T object(arg);
b) explicit copying of an existing object:
T original(arg);
...
T copy(original);
If T class has no copy constructor defined default implementation is created by compiler. It attempts to create an exact copy of the passed object. This is not always what programmer want, so custom implementation may be useful sometimes.
c) explicit creation of a brand new object in heap:
T *ptr = new T(arg);
d) implicit creation of a brand new object which constructor takes only one parameter and has no explicit modifier, for instance:
class T
{
public:
T(int x) : i(x) {}
private:
int i;
}
...
T object = 5; // actually implicit invocation of constructor occurs here
e) implicit copying of an object passed to a function by value:
void func(T input)
{
// here `input` is a copy of an object actually passed
}
...
int main()
{
T object(arg);
func(object); // copy constructor of T class is invoked before the `func` is called
}
f) implicit copying of an exception object handling by value:
void function()
{
...
throw T(arg); // suppose that exception is always raised in the `function`
...
}
...
int main()
{
...
try {
function();
} catch (T exception) { // copy constructor of T class is invoked here
// handling `exception`
}
...
}
g) Creation of a new object using assignment operator. I haven't used word 'copy' because in this case an assignment operator implementation of a particular type matters. If this operator is not implemented default implementation is created by compiler, btw it has the same behavior as default copy constructor.
class T
{
T(int x) : i(x) {}
T operator=() const
{
return T(*this); // in this implementation we explicitly call default copy constructor
}
}
...
int main()
{
...
T first(5);
T second = first; // assingment operator is invoked
...
}
Well, that's what I am able to remember without looking into Stroustrup's book. May be something is missed.
While I was writing this, some answer was accepted so I stop at this point. May the details I listed will be useful.

Why does this implementation of the C++ 'new' operator work?

I've found out that the C++ compiler for AVR uCs doesn't support the new and delete operators, but also that there is a quick fix:
void * operator new(size_t size)
{
return malloc(size);
}
void operator delete(void * ptr)
{
free(ptr);
}
I'm assuming that it would now be possible to call new ClassName(args);.
However, I am not really sure how this works. For example, what actually returns a size_t here? I thought that constructors don't return anything...
Could it be that new is now supposed to be used differently (in conjunction with sizeof())?
new T(args); is roughly equivalent to the following.
void* storage = operator new(sizeof(T)); // obtain raw storage
call_constructor<T>(storage, args); // make an object in it
(Here call_constructor is supposed to call the constructor† of T making storage be the this pointer within that constructor.)
The operator new part obtains the requested amount of raw storage, and the constructor call is the one that actually makes an object, by invoking the constructor.
The code in the question only replaces the operator new part, i.e. the retrieval of storage. Both the sizeof part and the constructor invocation are done automatically by the compiler when you use new T(args).
† The language has a way to express this direct constructor invocation called "placement new", but I omitted it for clarity.
From the compiler name (uC), I presume it's for embedded controller. This would make sense as you rarely require dynamic memory management with embedded devices, but might benefit from 'C with classes'. Hopefully it supports 'placement new' so you can actually use C++.
If your compiler doesn't support new & delete, it's not really much of a a C++ compiler is it!
I think the keyword 'new' effectively gets converted to:
Object* pointer = (Object *)new(sizeof Object);
pointer->Object_Constructor(args);

Access std::map within operator new called by static constructor

1) I have some static classes in my project that allocate variables within their constructors.
class StaticClass
{
public:
char *var;
StaticClass()
{
var=new char[100];
}
};
static StaticClass staticClass;
2) I have overridden the new and delete operators and made them keep track of all current allocations in a std::unordered_map
unordered_map<void*,size_t> allocations;
void* operator new[](size_t size)
{
void *p=malloc(size);
if (p==0) // did malloc succeed?
throw std::bad_alloc(); // ANSI/ISO compliant behavior
allocations[p]=size;
return p;
}
When my program starts, staticClass's constructor is called before allocations' constructor is, so operator new() tries to insert size into allocations before it has been initialized, which errors.
Previously, when I ran into problems with the order of static construction, I simply made the std::map into a NULL pointer, and then initialized it the first time it was used, ensuring it would be valid the first time I inserted it:
unsorted_map<void*,size_t> *allocations=NULL;
//in code called by static constructor:
if(allocations==NULL)
allocations=new unsortedmap()
//now safe to insert into allocations
However, this will no longer work since I would be calling new within operator new(), creating an infinite recursive loop.
I am aware that I could probably solve this by making another special version of operator new that takes some token argument to differentiate it, and just use that to initialize allocations, however in a more general (learning) sense, I would prefer to somehow either
a) force allocations to initialize before StaticClass does (best)
b) have some way to call the default operator new instead of my overridden one (which I don't think is possible, but...)
c) some other more general solution?
A simple way to avoid initialization order issues is to wrap your static object inside a function:
unordered_map<void*,size_t> &allocations()
{
static unordered_map<void*,size_t> static_map;
return static_map;
}
Then use it like this:
void* operator new[](size_t size)
{
void *p=malloc(size);
if (p==0) // did malloc succeed?
throw std::bad_alloc(); // ANSI/ISO compliant behavior
allocations()[p]=size;
return p;
}
However, you still run the risk of std::unordered_map using your operator new internally.