Skip to content

Commit 496332e

Browse files
committed
Upload note code of chapter 2 allocator
1 parent 791fbd5 commit 496332e

14 files changed

+1724
-0
lines changed

2_STL_allocator/2_1_1_jjalloc.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// file: 2jjalloc.cpp
2+
3+
#include "2_1_1_jjalloc.h"
4+
#include <vector>
5+
#include <iostream>
6+
using namespace std;
7+
8+
#define __ALIGN 8
9+
10+
int round_up(int b) {
11+
return (((b) + __ALIGN - 1) & ~(__ALIGN - 1));
12+
}
13+
14+
int main() {
15+
int ia[5] = {0, 1, 2, 3, 4};
16+
int i;
17+
18+
vector<int, JJ::allocator<int> > iv(ia, ia + 5);
19+
for (i = 0; i < iv.size(); i++) {
20+
cout << iv[i] << ' ';
21+
}
22+
cout << endl;
23+
24+
cout << ~(__ALIGN - 1) << endl;
25+
cout << round_up(3) << endl;
26+
cout << round_up(15) << endl;
27+
}

2_STL_allocator/2_1_1_jjalloc.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// file: 2jjalloc.h
2+
3+
#ifndef __JJALLOC__
4+
#define __JJALLOC_
5+
6+
#include <new> // for placement new
7+
#include <cstddef> // for ptrdiff_t, size_t
8+
#include <cstdlib> // for exit()
9+
#include <climits> // for UINT_MAX
10+
#include <iostream> // for cerr
11+
using namespace std;
12+
13+
// 在全局命名空间中有一个自带的、隐藏的operator new专门用来分配内存。
14+
// 默认情况下编译器会将new这个关键字翻译成这个operator new和相应的构造函数。
15+
// 但在有的情况下,用户自己会在类中重载operator new,这种情况下,编译器默认会使用类中重载的operator new
16+
// (本质上因为编译器会从命名空间由内而外查找自己想要的函数,选用第一个)。
17+
// 如果我们想要继续使用默认的operator new,就应该写成::new 字面意思就是调用最外层命名空间中的operator new
18+
// 值得一提的是最外层的(也是默认的)operator new也是可以被重载的。通过这种方式我们可以改变所有new的部分行为。
19+
20+
namespace JJ {
21+
// 配置空间,足以储存 n个 T对象。第二自变量是个提示。
22+
// 可能会利用它来增进区域性(locality),或完全忽略之。
23+
template <class T>
24+
inline T* _allocate(ptrdiff_t size, T*) {
25+
set_new_handler(0);
26+
T *tmp = (T *)(::operator new((size_t)(size * sizeof(T))));
27+
if (tmp == 0) {
28+
cerr << "out of memory" << endl;
29+
exit(1);
30+
}
31+
return tmp;
32+
}
33+
34+
// 归还先前配置的空间
35+
template <class T>
36+
inline void _deallocate(T* buffer) {
37+
::operator delete(buffer);
38+
}
39+
40+
// 等同于 new(const void*) p) T(x)
41+
template <class T1, class T2>
42+
inline void _construct(T1* p, const T2& value) {
43+
new (p) T1(value); // placement new. invoke ctor of T1
44+
}
45+
46+
// 等同于 p->~T()。
47+
template <class T>
48+
inline void _destroy(T* ptr) {
49+
ptr->~T();
50+
}
51+
52+
template <class T>
53+
class allocator {
54+
public:
55+
typedef T value_type;
56+
typedef T * pointer;
57+
typedef const T * const_pointer;
58+
typedef T & reference;
59+
typedef const T & const_reference;
60+
typedef size_t size_type;
61+
typedef ptrdiff_t difference_type;
62+
63+
// rebind allocator of type U
64+
template <class U>
65+
struct rebind {
66+
typedef allocator<U> other;
67+
};
68+
69+
// hint used for locality. ref. [Austern], p189
70+
pointer allocate(size_type n, const void* hint=0) {
71+
return _allocate((difference_type)n, (pointer)0);
72+
}
73+
74+
void deallocate(pointer p, size_type n) {
75+
_deallocate(p);
76+
}
77+
78+
void construct(pointer p, const T& value) {
79+
_construct(p, value);
80+
}
81+
82+
void destroy(pointer p) {
83+
_destroy(p);
84+
}
85+
86+
// 传回某个对象的地址。a.address(x)等同于 &x
87+
pointer address(reference x) {
88+
return (pointer)&x;
89+
}
90+
91+
// 传回某个 const对象的地址。a.address(x)等同于 &x
92+
const_pointer const_address(const_reference x) {
93+
return (const_pointer)&x;
94+
}
95+
96+
// 传回可成功配置的最大量
97+
size_type max_size() const {
98+
return size_type(UINT_MAX / sizeof(T));
99+
}
100+
};
101+
}
102+
#endif

2_STL_allocator/2_2_1_defalloc.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
*
3+
* Copyright (c) 1994
4+
* Hewlett-Packard Company
5+
*
6+
* Permission to use, copy, modify, distribute and sell this software
7+
* and its documentation for any purpose is hereby granted without fee,
8+
* provided that the above copyright notice appear in all copies and
9+
* that both that copyright notice and this permission notice appear
10+
* in supporting documentation. Hewlett-Packard Company makes no
11+
* representations about the suitability of this software for any
12+
* purpose. It is provided "as is" without express or implied warranty.
13+
*
14+
*/
15+
16+
// Inclusion of this file is DEPRECATED. This is the original HP
17+
// default allocator. It is provided only for backward compatibility.
18+
// This file WILL BE REMOVED in a future release.
19+
//
20+
// DO NOT USE THIS FILE unless you have an old container implementation
21+
// that requires an allocator with the HP-style interface.
22+
//
23+
// Standard-conforming allocators have a very different interface. The
24+
// standard default allocator is declared in the header <memory>.
25+
26+
#ifndef DEFALLOC_H
27+
#define DEFALLOC_H
28+
29+
#include <new.h>
30+
#include <stddef.h>
31+
#include <stdlib.h>
32+
#include <limits.h>
33+
#include <iostream.h>
34+
#include <algobase.h>
35+
36+
37+
template <class T>
38+
inline T* allocate(ptrdiff_t size, T*) {
39+
set_new_handler(0);
40+
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
41+
if (tmp == 0) {
42+
cerr << "out of memory" << endl;
43+
exit(1);
44+
}
45+
return tmp;
46+
}
47+
48+
49+
template <class T>
50+
inline void deallocate(T* buffer) {
51+
::operator delete(buffer);
52+
}
53+
54+
template <class T>
55+
class allocator {
56+
public:
57+
typedef T value_type;
58+
typedef T* pointer;
59+
typedef const T* const_pointer;
60+
typedef T& reference;
61+
typedef const T& const_reference;
62+
typedef size_t size_type;
63+
typedef ptrdiff_t difference_type;
64+
pointer allocate(size_type n) {
65+
return ::allocate((difference_type)n, (pointer)0);
66+
}
67+
void deallocate(pointer p) { ::deallocate(p); }
68+
pointer address(reference x) { return (pointer)&x; }
69+
const_pointer const_address(const_reference x) {
70+
return (const_pointer)&x;
71+
}
72+
size_type init_page_size() {
73+
return max(size_type(1), size_type(4096/sizeof(T)));
74+
}
75+
size_type max_size() const {
76+
return max(size_type(1), size_type(UINT_MAX/sizeof(T)));
77+
}
78+
};
79+
80+
81+
// 特化版本(Specialization),为什么无需加上template<>
82+
class allocator<void> {
83+
public:
84+
typedef void* pointer;
85+
};
86+
87+
88+
89+
#endif

2_STL_allocator/2_2_2_memory

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 1997-1999
3+
* Silicon Graphics Computer Systems, Inc.
4+
*
5+
* Permission to use, copy, modify, distribute and sell this software
6+
* and its documentation for any purpose is hereby granted without fee,
7+
* provided that the above copyright notice appear in all copies and
8+
* that both that copyright notice and this permission notice appear
9+
* in supporting documentation. Silicon Graphics makes no
10+
* representations about the suitability of this software for any
11+
* purpose. It is provided "as is" without express or implied warranty.
12+
*
13+
*/
14+
15+
#ifndef __SGI_STL_MEMORY
16+
#define __SGI_STL_MEMORY
17+
18+
#include <stl_algobase.h>
19+
#include <stl_alloc.h> // ���ﶨ����һ���������������˴˺�������������Ϊ alloc��
20+
#include <stl_construct.h> // ���ﶨ����ȫ��ʽconstruct()�� destroy()����������Ľ����ͽ⹹������������ STL ��׼�淶��
21+
#include <stl_tempbuf.h>
22+
#include <stl_uninitialized.h> // ���ﶨ����ȫ��ʽ���������fill�����ƣ�copy������ڴ����ݣ�����Ҳ�������� STL ��׼�淶
23+
#include <stl_raw_storage_iter.h>
24+
25+
26+
__STL_BEGIN_NAMESPACE
27+
28+
#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
29+
defined(__STL_MEMBER_TEMPLATES)
30+
31+
template<class _Tp1> struct auto_ptr_ref {
32+
_Tp1* _M_ptr;
33+
auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
34+
};
35+
36+
#endif
37+
38+
template <class _Tp> class auto_ptr {
39+
private:
40+
_Tp* _M_ptr;
41+
42+
public:
43+
typedef _Tp element_type;
44+
45+
explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
46+
auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
47+
48+
#ifdef __STL_MEMBER_TEMPLATES
49+
template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW
50+
: _M_ptr(__a.release()) {}
51+
#endif /* __STL_MEMBER_TEMPLATES */
52+
53+
auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
54+
if (&__a != this) {
55+
delete _M_ptr;
56+
_M_ptr = __a.release();
57+
}
58+
return *this;
59+
}
60+
61+
#ifdef __STL_MEMBER_TEMPLATES
62+
template <class _Tp1>
63+
auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW {
64+
if (__a.get() != this->get()) {
65+
delete _M_ptr;
66+
_M_ptr = __a.release();
67+
}
68+
return *this;
69+
}
70+
#endif /* __STL_MEMBER_TEMPLATES */
71+
72+
// Note: The C++ standard says there is supposed to be an empty throw
73+
// specification here, but omitting it is standard conforming. Its
74+
// presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2)
75+
// this is prohibited.
76+
~auto_ptr() { delete _M_ptr; }
77+
78+
_Tp& operator*() const __STL_NOTHROW {
79+
return *_M_ptr;
80+
}
81+
_Tp* operator->() const __STL_NOTHROW {
82+
return _M_ptr;
83+
}
84+
_Tp* get() const __STL_NOTHROW {
85+
return _M_ptr;
86+
}
87+
_Tp* release() __STL_NOTHROW {
88+
_Tp* __tmp = _M_ptr;
89+
_M_ptr = 0;
90+
return __tmp;
91+
}
92+
void reset(_Tp* __p = 0) __STL_NOTHROW {
93+
if (__p != _M_ptr) {
94+
delete _M_ptr;
95+
_M_ptr = __p;
96+
}
97+
}
98+
99+
// According to the C++ standard, these conversions are required. Most
100+
// present-day compilers, however, do not enforce that requirement---and,
101+
// in fact, most present-day compilers do not support the language
102+
// features that these conversions rely on.
103+
104+
#if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
105+
defined(__STL_MEMBER_TEMPLATES)
106+
107+
public:
108+
auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
109+
: _M_ptr(__ref._M_ptr) {}
110+
111+
auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW {
112+
if (__ref._M_ptr != this->get()) {
113+
delete _M_ptr;
114+
_M_ptr = __ref._M_ptr;
115+
}
116+
return *this;
117+
}
118+
119+
template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW
120+
{ return auto_ptr_ref<_Tp1>(this->release()); }
121+
template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
122+
{ return auto_ptr<_Tp1>(this->release()); }
123+
124+
#endif /* auto ptr conversions && member templates */
125+
};
126+
127+
__STL_END_NAMESPACE
128+
129+
#endif /* __SGI_STL_MEMORY */
130+
131+
132+
// Local Variables:
133+
// mode:C++
134+
// End:

0 commit comments

Comments
 (0)