PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : STL: eigener Allocator für std::map<>



7.e.Q
12-01-2006, 06:47
Guten Morgen,

ich möchte einen eigenen Allocator für die std::map<> implementieren, um dafür Sorge zu tragen, daß der für gelöschte Elemente der Map alloziierte Speicherbereich auch wirklich wieder freigegeben wird.

Ich habe angefangen, ein wenig mit custom allocators rumzuspielen, jedoch bekomme ich die ganzen Beispiele, die es im INet gibt nicht übersetzt. Ich bekomme beispielsweise immer die Fehlermeldung:



g++ -DISTSBIOS -DNCURSES -Wall -g -Icg -c -o obj/CGProcess.o CGProcess.cxx
In file included from CSysUnit.h:13,
from Client.h:20,
from main.h:42,
from main.cxx:22:
allocator.h:29: error: no type `const_pointer' in `std::bios_allocator<void>'
allocator.h:29: error: parse error before `=' token
allocator.h:29: error: template definition of non-template `T*
std::bios_allocator<void>::allocate(...)'
allocator.h:29: error: invalid member template declaration `T*
std::bios_allocator<void>::allocate(...)'

... und noch weitere. Dies ist allerdings die erste.


Die allocator.h sieht so aus. Stumpf abgetippt (Name von allocator auf bios_allocator geändert, weil der Compiler wegen Redefinition rumheulte), da ich noch nicht ganz verinnerlicht habe, was ich da tu; darum frage ich auch:



#ifndef __ALLOCATOR_H__
#define __ALLOCATOR_H__

#include <memory>

namespace std {
template<class T>
class bios_allocator
{
public:
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 bios_allocator<U> other; };

bios_allocator() throw();
bios_allocator(const bios_allocator&) throw();
template<class U> bios_allocator(const bios_allocator<U>&) throw();
~bios_allocator() throw();

pointer address(reference x) const;
const_pointer address(const_reference x) const;

pointer allocate(size_type, bios_allocator<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n);

void construct(pointer p, const T& val);
void destroy(pointer p);
template<class T1, class T2> bool operator==(const bios_allocator<T1>&, const bios_allocator<T2>&) throw();
template<class T1, class T2> bool operator!=(const bios_allocator<T1>&, const bios_allocator<T2>&) throw();
};

#endif


Kann mir jemand sagen, was da falsch ist?

7.e.Q
12-01-2006, 09:17
Hmm... also der "Fehler" war anscheinend bei



pointer allocate(size_type, bios_allocator<void>::const_pointer hint = 0);


Er konnte offenbar nichts mit bios_allocator<void>::const_pointer anfangen... geändert auf void*, schon lässt es sich übersetzen.

Aber nicht linken... jetzt bekomme ich folgende Fehlermeldung beim Linken:



g++ -o ists_tcp obj/main.o obj/PortToSlot.o obj/CBGInfo.o obj/curses.o obj/allocator.o obj/CConsole.o obj/md5.o obj/CGProcess.o obj/CSysUnit.o obj/CSysUnit_2.o obj/CSysUnit_SF.o obj/ToolObserver.o obj/Server.o obj/Client.o obj/File.o obj/CInfoServer.o obj/StringFuncs.o obj/CUTAPipe.o obj/NTPDController.o obj/DateFunctions.o obj/Timer.o obj/CMain_daemon.o obj/idffile.o obj/util.o obj/bits.o obj/blockzip.o obj/deflate.o obj/inflate.o obj/trees.o obj/idfrec.o obj/omaincgx.o -lncurses -lpanel -lm -lreadline -lhistory
obj/CSysUnit.o(.gnu.linkonce.t._ZNSt19_Rb_tree_alloc_b aseISt4pairIKSsSsESt14bios_allocatorIS0_ISsSsEELb0 EE11_M_put_nodeEPSt13_Rb_tree_nodeIS2_E+0x12): In function `std::_Rb_tree_alloc_base<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::bios_allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, (bool)0>::_M_put_node(std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*)':
/usr/include/c++/3.3.3/bits/stl_tree.h:982: undefined reference to `std::bios_allocator<std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::deallocate(std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, unsigned)'


template<class Typ> bios_allocator<Typ>::allocate sieht folgendermaßen aus:



template<class Typ> bios_allocator<Typ>::pointer bios_allocator<Typ>::allocate(bios_allocator<Typ>::size_type len, void* hint)
{
return (static_cast<bios_allocator<Typ>::pointer>(malloc( anz*sizeof(Typ) ) ) );
}

7.e.Q
12-01-2006, 11:58
Okay, also den Speicherfresser, den ich hatte, hab ich gefunden... War nicht die map. War mir auch von vornherein klar, weil's ja fertiger Code ist, der dahintersteckt. Wäre da 'n Speicherfresser drin gewesen, wäre das wohl schon aufgefallen... Eigentlich irgendwo schon fast Blasphemie zu denken, daß in der STL irgendwo ein Fehler drin ist. :eek:

Trotzdem fände ich es sehr interessant, einmal zu erfahren, wie man einen Allocator für eine std::map<> erstellt. :cool: