g++ user defined allocator

Xiaowen (Jason) Liu jasonliu@cs.dartmouth.edu
Mon Jul 8 10:18:00 GMT 2002


I met a problem with darwin's new gcc/g++ compiler. I attached the a 
simple version of the code in the following to show the problem. I 
defined a memory allocator, which does nothing unexpected and I used it 
as the allocator for "string". When I compile it, it gives me the 
following error messages:

% g++3 abc.cc
ld: Undefined symbols:
__ZNSbIcSt11char_traitsIcE11DaSSF_ALLOCIcEE20_S_empty_rep_storageE
__ZNSbIcSt11char_traitsIcE11DaSSF_ALLOCIcEE4_Rep11_S_max_sizeE
__ZNSbIcSt11char_traitsIcE11DaSSF_ALLOCIcEE4_Rep11_S_terminalE

% g++3 -v
Reading specs from /usr/libexec/gcc/darwin/ppc/3.1/specs
Thread model: posix
Apple Computer, Inc. GCC version 1041, based on gcc version 3.1 20020105 
(experimental)

When I compile it on Linux (gcc-v3), however, there's no problem at all. 
I hope someone keen on using STL can give me some help.

THANKS.

-jason.


-------- cut here (abc.cc) -----------------
#include <algorithm>
#include <cstddef>
#include <cstdlib>
#include <climits>

#include <string>
#include <iostream>

//#define DEBUG_DASSF_ALLOC

template <class T>
class DaSSF_ALLOC {
  public:
   typedef T value_type;
   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;

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

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

   static pointer allocate(size_type n, 
/*DaSSF_ALLOC<void>::const_pointer*/const void* = 0) {
#ifdef DEBUG_DASSF_ALLOC
     cerr << "allocate " << n << " element(s)"
          << " of size " << sizeof(T) << endl;
#endif
     pointer ret = (pointer)(::operator new(n*sizeof(T)));
#ifdef DEBUG_DASSF_ALLOC
     cerr << " allocated at: " << (void*)ret << std::endl;
#endif
     return ret;
   }

   static void deallocate(/*pointer*/void* p, size_type n) {
#ifdef DEBUG_DASSF_ALLOC
     cerr << "deallocate " << n << " element(s)"
          << " of size " << sizeof(T)
          << " at: " << (void*)p << endl;
#endif
     ::operator delete((void*)p);
   }

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

   //size_type max_size() const throw() { return LONG_MAX/sizeof(T); }
   size_type max_size() const throw() {
     return std::max(size_type(1), size_type(UINT_MAX/sizeof(T)));
   }

   template <class U>
   struct rebind { typedef DaSSF_ALLOC<U> other; };
};

template<class T>
bool operator == (const DaSSF_ALLOC<T>&,
                   const DaSSF_ALLOC<T>&) throw() {
   return true;
}

template <class T>
bool operator != (const DaSSF_ALLOC<T>&,
                   const DaSSF_ALLOC<T>&) throw() {
   return false;
}

int main()
{
   typedef 
std::basic_string<char,std::char_traits<char>,DaSSF_ALLOC<char> > mystring;
   mystring x = "hello world!\n";
   std::cout << x;
   return 0;
}



More information about the Gcc-help mailing list