using a vector in a custom memory manager - c++

I am writing a memory manager in c++. The aim is to allocate a set amount of memory at the start using malloc and then overload new and delete so that it uses that memory. I almost have it working my only problem is how i am keeping track of what is where in the memory.
I created a vector of structs which holds information such as size, location and if it is free or not.
The problem is when i call push_back it attempts to use my overloaded new function. This is where it fails because it can't use my overloaded new until it has pushed back the first structure of information.
Does anyone know how i can resolve this or a better way to keep track of the memory?

Don't overload global operator new!
The easiest and (WARNING; subjective ->) best solution would be to define your own Allocator which you'll use when dealing with allocation on the free-store (aka. heap). All STL containers have support for passing an AllocatorType as a template argument.
Overloading global operator new/operator delete might seem like a neat solution, but I can almost guarantee you that it will cause you troubles as the developing goes by.
Inside this custom made allocator you can keep track of what goes where, but make the internal std::vector (or whatever you'd like to use, a std::map seems more fitting to me) will use the default operator new/operator delete.
How do I create my own allocator?
The link below will lead you to a nice document with information regarding this matter:
stdcxx.apache.org - Building Your Own Allocators (heavily recommended)
Using a custom allocator when required/wanted will make you not run into any chicken and egg problem when trying to allocate memory for the allocator that will allocate memory, but the allocator must have allocated memory to use the allocator methods.. and what will allocate memory for the allocator but the allocator? Well we will need to allocate memory for that allocator and that allocator must have it's own allocator, though that allocator need memory, provided by another allocator?
Maybe I should just get myself a dog instead, they don't lay eggs - right?

create a class and overload new only in this class. you will not have problems with your vector. you will be able to use your own new with ::new A and the normal new with new A
class C
{
public:
void* operator new( size_t n ) ;
// ...
} ;
otherwise, you can use your own operator function rather than overload operator new :
a basic idea of an allocator :
int *i = myGetMem(i); // and myGetMem() allocates sizeof(*i) bytes of memory.
so you will not have problems with using the vector.
in fact, a real memory allocator keeps the information you put on the vector in the memory allocated it self :
you can take an algorithm for getmem/freemem to adapt it to your case. it can be helpfull.
e.g. : i want to allocate 10 bytes, the memory at #1024 contain information about memory allocated and the allocator returns an adress after 1024, maybe #1030 (depending of the information stored) as the start of allocated memory. so the user gets adress 1030 and he has memory between 1030 and 103A.
when calling the deallocator, the information at the beginning is used to correctly free the memory and to put it back in the list of avaible memory.
(the list of availvle memory is stored in popular alorithms in an array of linked lists of free memories organized by size with algorithms to avoid and minimize fragmentation)
this can resolve your need to the vector.

You can create a vector using any custom allocator.
It is declared in the following manner:
std::vector<YourStruct, YourOwnAllocator> memory_allocations;
YourOwnAllocator is going to be a class which will allocate the data needed for the vector bypassing your overloaded operators.
In needs to provide all the methods and typedefs listed here.

Related

I don't understand how new node has been created without pointer to node [duplicate]

I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this pointer of Fred will be equal to place.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
template<typename T>
class SillyVectorExample
{
public:
SillyVectorExample()
:reserved(10)
,size(0)
,data(new char[sizeof(T) * reserved])
{}
void push_back(T const& object)
{
if (size >= reserved)
{
// Do Somthing.
}
// Place a copy of the object into the data store.
new (data+(sizeof(T)*size)) T(object);
++size;
}
// Add other methods to make sure data is copied and dealllocated correctly.
private:
size_t reserved;
size_t size;
char* data;
};
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
I've used it when constructing objects in a shared memory segment.
Placement new can be used to create type-safe unions, such as Boost's variant.
The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
seems to me like a way of allocating an object on the stack ..
I've used it to create objects based on memory containing messages received from the network.

Difference between an allocator and a built in array in c++?

I have lately been trying to create custom containers that are similar to some of the library containers (i.e vector, list). and while I was using an allocator to allocate dynamic memory I noticed that the idea behind allocators and built in arrays are the same. allocators reserve a certain amount of raw, unconstructed dynamic memory and return a pointer to the first free location in that pool of memory. and built in arrays pretty much do the same thing. so if we have an std::allocator for strings called alloc
this codealloc.allocate(7) and this code string* array = new string[7] should have the same effect. and if we want to construct the raw memory we can call std::allocator::construct passing it the pointer returned from the allocate function, or we can have something like array[0] = string("something") to do the same thing. correct?
so what is there a difference between how an allocator work and how a built in array work?
You're right that they're fundamentally related, but not in that way. new string[7] could indeed be decomposed into allocate and construct (with a few extra bits for EH and other details).
Separating them out in the allocator interface allows much more fine-grained control for containers so that they can, for example, have memory with non-constructed objects in them, which is often vital for correct performance guarantees or semantics.
Additionally, The allocator interface is, of course, an interface with many possible implementations, such as memory arenas or object pools, which new string[7] really doesn't offer.
Finally, new T[] is shit and don't ever use it. The allocator interface is designed to be used only by fairly experienced programmers in quite limited ways- as a component of a better library component. new T[] is a language feature that everybody can just use, with terrible results.
An array is collinear container of slots for items in memory. The array is a range.
An allocator is an function object (or function) that reserves memory. The allocator can designate space from an array, stack, heap, or other areas of memory. The allocator can also be used to allocate space outside of the memory area, such as a hard drive or other device (maybe a server, cloud, etc.)
The space allocated for an array is usually determined by the compiler during the build phase.
An allocator is used for dynamic (during run-time) allocation of objects.

C++ : vector standard template library

In C++ STL vector is a dynamic array, but it performs operations like a stack. So can any one please tell whether data is stored in stack or heap segment.
std::vector itself doesn't define how the memory it uses is allocated. It does memory allocation via an Allocator object.
By default, a vector<T> will use an std::allocator<T> to handle allocation. That, in turn, will use operator new and operator delete to allocate/delete memory.
Those are all subject to change though--the type for the Allocator is passed to vector as a template parameter, so if you want to write an Allocator class that does allocation differently, you're entirely free to do that. Assuming it meets the requirements on an allocator, you can then create instances of std::vector that use your allocator instead of the default one.
You can also provide replacements for operator new and operator delete on a class-by-class and/or global basis. If you do so, std::allocator<T> will use your allocation/deletion routines instead of those defined in the standard library.
It's stores it's elements in a contiguous block on the heap. It can be locally created or dynamically allocated. And finally even a simple c-style array can be used as a stack.
Anything stored in a Vector is stored in contiguous memory in the heap.
It is also not designed to act as a stack, although you could use it to implement stack operations, it is (probably) more effiecient to use an actual stack implementation in that case.*
It is worth noting that the memory used by a Vector can be changed as adding or removing elements can cause it to re-allocate memory.
*If you pre-allocate memory beforehand, then most implementations of a stack will be roughly as efficent as any other.
"
vector<Type> vect;
will allocate the vector, i.e. the header info, on the stack, but the elements on the free store ("heap").
vector<Type> *vect = new vector<Type>;
allocates everything on the free store.
vector<Type*> vect;
will allocate the vector on the stack and a bunch of pointers on the free store, but where these point is determined by how you use them (you could point element 0 to the free store and element 1 to the stack, say)."
Your question is answered by larsmans at 7-11-11.Your welcome.

What to do in class specific version of placement new?

Class-specific version of placement new can be provided even though you can't replace the global one. What scenarios exist where a class should provide its own placement new operator?
Even if my class don't implement placement new the following code works (assuming for abc no operator new is overloaded).
char arr[100];
abc *pt = new(&arr)abc;
So i interpret, there is some default placement new but for class we can provide our own version of operator new, my question is what is the use case for that?
What one is supposed to do other then returning the same pointer that is passed? Is there any useful example/scenario that you encountered?
Sounds like a quiz question...
Faster and Leaner Allocation
The most common reason is a lot of small objects that need to be allocated dynamically. A custom allocator for fixed-size objects has much less allocation overhead than a generic allocator, does not suffer from fragmentation, and is typically faster. (Also, when these allocations are removed from the main heap, they don't contribute to main heap fragmentation anymore).
Similary, a non-freeing allocator (where you can allocate multiple objects, but can't free them together, only in conjunction) is the fastest allocation scheme possible, and does not have any overhead (except alignment in a few rare cases). It makes sense if you are building a data structure that you never modify, only delete as a whole.
Other base allocator
Another application is allocating from a different heap than the C++ heap.
Maybe the data in the objects needs to be allocated in shared memory for exchange with other processes, or it needs to be passed to a system function that takes ownership and requries the use of a certain allocator. (Note that this requires to implement the same mechanism for all sub-objects, too, there is no generic way to achieve that).
Similary (where I use it) is when you create code on the fly. Nowadays, you need to tell the OS that data on this memory page is allowed to run, but you get this memory in rather large chunks (e.g. 4K). So again, request a page (4K) from the OS with execution rights, then allocate many small objects on top of it - using placement new.
Unfortunately, AFAIK, you cannot do a class specific overload of the standard placement new operator, only of custom placement new operators. So a use-case for it is a bit academic, but I wanted to use it to forbid placement new on the class by using = delete of C++11. This works great with standard operator new but not for placement new.
Straight from the horse's mouth wiki. The section titled 'Use' highlights the need for placement new.
This SO thread here might also help
UPDATE:
To specifically answer you question; You might use the standard placement new provided by header <new> if you have a pool of memory you want to use for constructing some objects of a class, but don't want to overload operator new for the whole class. In the latter case all the class objects are placed as per the overloaded placement new as defined in the class
i'm not sure that its possible to overload the placement new, only the regular new. i can't think of even a single use for that, since the only possible implementation is just creating a temp object and memcp'ing it to the given memory address - since you're not supposed to allocate any other memory in there, but use the given one.

What are uses of the C++ construct "placement new"?

I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this pointer of Fred will be equal to place.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
template<typename T>
class SillyVectorExample
{
public:
SillyVectorExample()
:reserved(10)
,size(0)
,data(new char[sizeof(T) * reserved])
{}
void push_back(T const& object)
{
if (size >= reserved)
{
// Do Somthing.
}
// Place a copy of the object into the data store.
new (data+(sizeof(T)*size)) T(object);
++size;
}
// Add other methods to make sure data is copied and dealllocated correctly.
private:
size_t reserved;
size_t size;
char* data;
};
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
I've used it when constructing objects in a shared memory segment.
Placement new can be used to create type-safe unions, such as Boost's variant.
The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
seems to me like a way of allocating an object on the stack ..
I've used it to create objects based on memory containing messages received from the network.