Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 1, средняя оценка - 5.00
Droll
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
#1

allocator своя версия - C++

02.06.2013, 19:01. Просмотров 706. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.06.2013, 19:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос allocator своя версия (C++):

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

Распределитель памяти идентичный std::allocator. Непонятные синтаксис и концепция std::allocator::construct - C++
Компилятор: MSVC 2010 Exress код моего класса распределяющего память под спойлером #include <stdlib.h> // my memory allocator...

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

std::allocator - C++
Здравствуйте! Подскажите почему возникает ошибка сегментирования: using std::cout; using std::endl; int main() { ...

Allocator и shared_ptr - C++
Прокомментируйте пожалуйста. Есть ли смысл и вообще возможность оформлять зарезервированную память allocator-ом в shared_ptr? Или это...

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

8
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
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
Droll
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
03.06.2013, 11:19  [ТС] #3
Спасибо за ответ. А что нужно сделать, чтоб работало со стандартными контейнерами?
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
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
Droll
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
03.06.2013, 11:31  [ТС] #5
я так и думал. а можете объяснить почему не работает со стандартными контейнерами? если не сложно.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
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
Droll
0 / 0 / 0
Регистрация: 07.09.2012
Сообщений: 48
03.06.2013, 12:53  [ТС] #7
Спасибо большое!
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.06.2013, 13:12 #8
ForEveR, кстати, пользуясь случаем хотел спросить: если не смотреть на требование ТС
Цитата Сообщение от Droll Посмотреть сообщение
Default: returns malloc (n*sizeof(T))
есть ли смысл использовать глобальный operator new взамен malloc?
В VS2010 например в итоге всё равно вызывается malloc. А в самом днище упираемся в HeapAlloc.
Как в других реализациях, есть ли гдe new не на базе malloc?
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
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
03.06.2013, 13:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.06.2013, 13:23
Привет! Вот еще темы с ответами:

Ошибка с allocator - C++
Приветствую. Пользуюсь Dev-C++. При выполнении кода, ошибка, что на скрине. #include &lt;iostream&gt; int main() { ...

Vector allocator SQLite - C++
Гуру, помогите новичку! Столкнулся с проблемой, и даже не понимаю в чем она... Надо: сделать список(вектор) для хранения ссылок...

allocator std::map - C++
Подскажите вопрос, есть тестовое задание: Подскажите где про это почитать и разъясните по-возможности, что это вообще такое...

allocator, при компиляции ошибка - C++
template&lt;class T&gt; class Vec { public: ... private: allocator&lt;T&gt; alloc; ... }


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

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

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