Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
1

allocator своя версия

02.06.2013, 19:01. Просмотров 902. Ответов 8
Метки нет (Все метки)

Доброго времени суток.
Мне нужно написать class allocator на подобии стандартного. Он должен содержать следующие методы:
Method void* allocate (size_t n)
Default: returns malloc (n*sizeof(T))
Method void deallocate (void* pointer)
Default: free(pointer)
Method void construct ( void* p, const T& value)
new(p) T(value);
Method void destroy (T* p)
p->~T();

Я понимаю, что allocate строит память и не вызывается конструктор. Мне не совсем понятно должны ли быть какие-то поля в классе? И если не сложно, напишите (или укажите где можно найти) пример написания подобного allocatora.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.06.2013, 19:01
Ответы с готовыми решениями:

Своя версия функции strcmp()
В книге дано задание, создать свою версию функции strcmp(). Подскажите как можно это реализовать,...

Распределитель памяти идентичный std::allocator. Непонятные синтаксис и концепция std::allocator::construct
Компилятор: MSVC 2010 Exress код моего класса распределяющего память под спойлером #include...

Своя версия программы rm
Всем привет, нужно написать такую программу: Напишите свою версию программы rm, используя вызов...

allocator
Здорова! Есть задачка:"Завершите или реализуйте с самого начала Pool_alloc (параграф 19.4.2) так,...

8
В астрале
Эксперт С++
8023 / 4780 / 654
Регистрация: 24.06.2010
Сообщений: 10,558
03.06.2013, 11:09 2
Вполне достаточно будет этого.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template<typename T>
class allocator : public std::allocator<T>
{
public:
   typedef std::allocator<T> base;
 
   void* allocate(typename base::size_type n, const void* = 0)
   {
      return malloc(n * sizeof(T));
   }
   void deallocate(void* p, typename base::size_type)
   {
      free(p);
   }
   void construct(void* p, const T& value)
   {
      new (p) T(value);
   }
   void destruct(T* p)
   {
      p->~T();
   }
};
Но это не будет работать со стандартными контейнерами, т.к. allocate возвращает void*.
1
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
03.06.2013, 11:19  [ТС] 3
Спасибо за ответ. А что нужно сделать, чтоб работало со стандартными контейнерами?
0
В астрале
Эксперт С++
8023 / 4780 / 654
Регистрация: 24.06.2010
Сообщений: 10,558
03.06.2013, 11:23 4
Droll, Вовращать T*. Т.е.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template<typename T>
class allocator : public std::allocator<T>
{
public:
   typedef std::allocator<T> base;
 
   typename base::pointer allocate(typename base::size_type n, const void* = 0)
   {
      return static_cast<typename base::pointer>(malloc(n * sizeof(T)));
   }
   void deallocate(void* p, typename base::size_type)
   {
      free(p);
   }
   void construct(void* p, const T& value)
   {
      new (p) T(value);
   }
   void destruct(T* p)
   {
      p->~T();
   }
};
2
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
03.06.2013, 11:31  [ТС] 5
я так и думал. а можете объяснить почему не работает со стандартными контейнерами? если не сложно.
0
В астрале
Эксперт С++
8023 / 4780 / 654
Регистрация: 24.06.2010
Сообщений: 10,558
03.06.2013, 11:46 6
Droll, В С++ запрещено неявное преобразование от void* к T*, т.е. такой код не скомпилируется
C++
1
2
3
4
5
6
#include <cstdlib>
 
int main()
{
   int* p = malloc(sizeof(int));
}
Поэтому нужно добавлять явное преобразование.

C++
1
2
3
4
5
6
#include <cstdlib>
 
int main()
{
   int* p = static_cast<int*>(malloc(sizeof(int)));
}
Контейнеры рассчитывают на то, что allocate будет возвращать
C++
1
allocator::pointer
, потому не делают явных кастов.

Добавлено через 11 минут
Ну и в + без наследования от аллокатора, ежели вдруг оно не нужно.

C++
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <cstdlib>
#include <memory>
#include <vector>
 
template<typename T>
class allocator
{
public:
   typedef T value_type;
   typedef T* pointer;
   typedef const T* const_pointer;
   typedef T& reference;
   typedef const T& const_reference;
   typedef size_t size_type;
   typedef ptrdiff_t difference_type;
 
   template<typename U>
   struct rebind
   {
      typedef allocator<T> other;
   };
 
   allocator() {}
   allocator(const allocator&) {}
   template<typename U>
   allocator(const allocator<T>&) {}
 
   pointer allocate(size_type n, const void* = 0)
   {
      return static_cast<pointer>(malloc(n * sizeof(T)));
   }
   void deallocate(pointer p, size_type)
   {
      free(p);
   }
   void construct(pointer p, const T& value)
   {
      new (p) T(value);
   }
   void destruct(pointer p)
   {
      p->~T();
   }
   size_type max_size()
   {
      return std::allocator<T>::max_size();
   }
   pointer address(reference x) const
   {
      return const_cast<pointer>(address(const_cast<const_reference>(x)));
   }
   const_pointer address(const_reference x) const
   {
      return std::allocator<T>().address(x);
   }
};
 
template<typename T>
bool operator == (const allocator<T>&, const allocator<T>&)
{
   return true;
}
 
template<typename T>
bool operator != (const allocator<T>& lhs, const allocator<T>& rhs)
{
   return !(lhs == rhs);
}
 
int main()
{
   std::vector<int, allocator<int> > vector;
   vector.push_back(1);
}
2
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
03.06.2013, 12:53  [ТС] 7
Спасибо большое!
0
:)
Эксперт С++
4763 / 3257 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.06.2013, 13:12 8
ForEveR, кстати, пользуясь случаем хотел спросить: если не смотреть на требование ТС
Цитата Сообщение от Droll Посмотреть сообщение
Default: returns malloc (n*sizeof(T))
есть ли смысл использовать глобальный operator new взамен malloc?
В VS2010 например в итоге всё равно вызывается malloc. А в самом днище упираемся в HeapAlloc.
Как в других реализациях, есть ли гдe new не на базе malloc?
0
В астрале
Эксперт С++
8023 / 4780 / 654
Регистрация: 24.06.2010
Сообщений: 10,558
03.06.2013, 13:23 9
Tulosba, Не знаю, не интересовался честно говоря особо.
Default behavior:
— Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether
the attempt involves a call to the Standard C library function malloc is unspecified.

— Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to
set_new_handler() was a null pointer, throw bad_alloc.
— Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop
repeats.
— The loop terminates when an attempt to allocate the requested storage is successful or when a called
new_handler function does not return.
У clang (libc++) такое:

C++
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
__attribute__((__weak__, __visibility__("default")))
void *
operator new(std::size_t size)
#if !__has_feature(cxx_noexcept)
    throw(std::bad_alloc)
#endif
{
    if (size == 0)
        size = 1;
    void* p;
    while ((p = ::malloc(size)) == 0)
    {
        // If malloc fails and there is a new_handler,
        // call it to try free up memory.
        std::new_handler nh = std::get_new_handler();
        if (nh)
            nh();
        else
#ifndef _LIBCPP_NO_EXCEPTIONS
            throw std::bad_alloc();
#else
            break;
#endif
    }
    return p;
}
 
__attribute__((__weak__, __visibility__("default")))
void
operator delete(void* ptr) _NOEXCEPT
{
    if (ptr)
        ::free(ptr);
}
Ну и в libstdc++

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
  void *p;
 
  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
    _GLIBCXX_THROW_OR_ABORT(bad_alloc());
      handler ();
      p = (void *) malloc (sz);
    }
 
  return p;
}
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.06.2013, 13:23

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Китайский JTAG RealView ULINK2 версия прошивки и версия Keil
Есть китайский клон 20-pin JTAG очень похожий на Keil-вый. Какую версию Keil с ним можно...

Какая версия версия GCC сейчас самая безглючная?
Собираю проект. Проект заведомо рабочий. а у меня, почему-то он не работает. На проверенной плате....

std::allocator
Здравствуйте! Подскажите почему возникает ошибка сегментирования: using std::cout; using...

std::allocator
я не смог найти хорошего описания роботы с аллокатором, так что спрашиваю у тех, кто с ним работал...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.