11

STLにmalloc/freeベースのアロケータはありますか?そうでない場合、誰かが簡単なコピー/貼り付けを知っていますか?new/deleteを呼び出さないマップに必要です。

4

2 に答える 2

11

まず、マップ自体のアロケータを変更しても、マップに格納されているオブジェクトが使用する割り当ては変更されないことに注意してください。たとえば、次のようなことをするとします。

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

マップ自体は指定されたアロケーターを使用してメモリを割り当てますが、マップ内の s がメモリを割り当てるときは、std::string引き続きデフォルトのアロケーターを使用します (これは and を使用newdeleteます。したがって、回避する必要がある場合newdelete一般的には、確実にする必要がありますマップ自体が正しいアロケーターを使用するだけでなく、マップに格納されているすべてのオブジェクトが同じことを行うことを確認します (これはおそらく明白なことを述べていることはわかっていますが、見落としていたので、言及する価値があるかもしれません)。

その但し書きで、コードを続けます:

#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

そして、ちょっとしたテストコード:

#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;
}
于 2012-07-10T16:30:02.133 に答える
0

実際、@MichaelBurr が示唆するように、Lavavej の「mallocator」である Stephen J が探しているものです。今日の@Arnaudによるこの回答で、更新されたきれいなコードを取得しました。見てください。

于 2016-04-09T20:22:59.837 に答える