简体   繁体   中英

malloc/free based STL allocator

Is there a malloc/free based allocator in the STL? If not, does anyone know of a simple copy/paste one? I need it for a map that must not call new/delete.

First, I'd note that changing the allocator for the map itself won't change the allocation used by the objects stored in the map. For example, if you do something like:

std::map<std::string, int, my_allocator<std::pair<const std::string, int> > m;

The map itself will allocate memory using the specified allocator, but when the std::string s in the map allocate memory, they'll still use the default allocator (which will use new and delete . So, if you need to avoid new and delete in general, you have to ensure that not only the map itself uses the right allocator, but that any objects it stores do the same (I know that's probably stating the obvious, but I've overlooked it, so maybe it's worth mentioning).

With that proviso, on with the code:

#ifndef ALLOCATOR_H_INC_
#define ALLOCATOR_H_INC_

#include <stdlib.h>
#include <new>
#include <limits>

namespace JVC {
template <class T> 
struct allocator {
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T value_type;

    template <class U> struct rebind { typedef allocator<U> other; };
    allocator() throw() {}
    allocator(const allocator&) throw() {}

    template <class U> allocator(const allocator<U>&) throw(){}

    ~allocator() throw() {}

    pointer address(reference x) const { return &x; }
    const_pointer address(const_reference x) const { return &x; }

    pointer allocate(size_type s, void const * = 0) {
        if (0 == s)
            return NULL;
        pointer temp = (pointer)malloc(s * sizeof(T)); 
        if (temp == NULL)
            throw std::bad_alloc();
        return temp;
    }

    void deallocate(pointer p, size_type) {
        free(p);
    }

    size_type max_size() const throw() { 
        return std::numeric_limits<size_t>::max() / sizeof(T); 
    }

    void construct(pointer p, const T& val) {
        new((void *)p) T(val);
    }

    void destroy(pointer p) {
        p->~T();
    }
};
}

#endif

And, a little test code:

#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <iterator>
#include "allocator.h"

// Technically this isn't allowed, but it's only demo code, so we'll live with it.
namespace std { 
std::ostream &operator<<(std::ostream &os, std::pair<std::string, int> const &c) { 
    return os << c.first << ": " << c.second;
}
}

int main() { 
    std::map<std::string, int, std::less<std::string>, 
             JVC::allocator<std::pair<const std::string, int> > > stuff;

    stuff["string 1"] = 1;
    stuff["string 2"] = 2;
    stuff["string 3"] = 3;

    std::copy(stuff.begin(), stuff.end(), 
        std::ostream_iterator<std::pair<std::string, int> >(std::cout, "\n"));

    return 0;
}

Indeed, as @MichaelBurr suggests, Stephen J, Lavavej's 'mallocator' is what you're looking for. I just got updated and prettied-up code for it in this answer by @Arnaud today, do have a look.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM