Custom allocator issue

I think I've gotten a very basic allocator class written up, but I can't figure out how to actually construct anything in this space given:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
template <typename T> class MemoryManager
{
    public:
        T* allocate(size_t n) const;
        void deallocate(T* const buffer) const;
        size_t max_size() const;
        MemoryManager() {};
};

template <typename T>
T* MemoryManager<T>::allocate(size_t n) const
{
    if(n == 0)
        return NULL;

    if(n > max_size())
    {
        throw std::length_error("Integer overflow at MemoryManager::allocate()");
    }

    T* buffer = static_cast<T*>(malloc(n * sizeof(T)));

    if(buffer == NULL)
    {
        throw std::bad_alloc();
    }

    std::cout << "Buffer allocated.\n";
    return buffer;
}

template <typename T>
void MemoryManager<T>::deallocate(T* const buffer) const
{
    free(buffer);
    std::cout << "Buffer deallocated.\n";
}

template <typename T>
size_t MemoryManager<T>::max_size() const
{
    return (std::numeric_limits<std::size_t>::max() / sizeof(T));
}


Main:
1
2
3
MemoryManager<Test> mem;
    Test* test = mem.allocate(10);
    test[2] = new Test;


This didn't work. I have no operator= defined for Test, but how do I go about actually initializing objects in this space?

EDIT:
This works:
1
2
3
4
MemoryManager<Test> mem;
    Test* test = mem.allocate(10);
    Test test2;
    test[2] = test2;


This is how I imagine this should work. I get the space allocated, construct objects however I want, then put them this space. But, this seems like I'm creating an object on the stack, then placing a copy of it on the heap. Is this normal? I've never dabbled with memory management in this manner before, so I'm still a little lost, and it's hard to find resources on this. So far I've only really managed to find an article by IBM on memory management systems.
Last edited on
using an allocator, which is what you do in a vector, shared_ptr, function, or another allocator-aware class is a whole different story from writing an allocator that all existing allocator-aware class can use.
In a vector, you would call the function construct(), provided by allocator_traits (as of C++11) or directly by the allocator. Assignment to uninitialized memory is only valid for trivially-copyable types.
I saw this
1
2
3
4
5
6
template <typename T>
size_t MyAllocator<T>::max_size() const
{
    /** What does this do? :O **/
    return ((static_cast<size_t>(0) - static_cast<size_t>(1)) / sizeof(T));
}
while looking at http://iweb.dl.sourceforge.net/project/myalloc/MyAllocator.h from ResidentBiscuits project http://sourceforge.net/projects/myalloc/ and I'm just not seeing how it returns what it does, so if anyone can explain why lines 8 and 9 in http://ideone.com/YbQR65 return the same value as line 10.
Last edited on
Isn't it simply like...
return (0U - 1U) / sizeof(T);
which is also like
return -1 / sizeof(T);
or
return 0xFFFFFFFF / sizeof(T);
or
return UINT_MAX / sizeof(T);
??
It essentially does:

return std::numeric_limits<std::size_t>::max() / sizeof(T) ;

-1 in 2's complement machines (which the majority of computers are) is the same bit respresentation (all bits set) as the maximum unsigned value.
Last edited on
Ok that makes sense. I didn't realize it would result in an unsigned value. Thank you for the explanation.
You're missing a few typedefs to be a plug in replacement for std::allocator.
I have it changed to what cire has posted, as I think it's much more readable. From The Mallocator though, the author said that his way is implementation dependent, though I don't see how this way would be otherwise?

@kbw,
Yea I know, I'm missing several things for that. I'm currently just trying to get the bare essentials working. As this is all new grounds for me I'm trying to work on one thing at a time.
Topic archived. No new replies allowed.