日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STL内存分配

發布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STL内存分配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

1.??????Stl內存創建基類模板__malloc_alloc_template

STL的常用的內存創建參考文件: stl_alloc.h,文件中定義了__malloc_alloc_template模板庫,創建與釋放使用C方法mallocfreerealloc,模板庫里面主要對外提供了函數:

allocate:?分配內存

deallocate:?釋放內存

reallocate:?重新分配內存

__set_malloc_handler:?設置異常處理函數

template <int __inst>

class __malloc_alloc_template {

?

private:

?

? static void* _S_oom_malloc(size_t);

? static void* _S_oom_realloc(void*, size_t);

?

#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG

? static void (* __malloc_alloc_oom_handler)();

#endif

?

public:

?

? static void* allocate(size_t __n)

? {

??? void* __result = malloc(__n);

??? if (0 == __result) __result = _S_oom_malloc(__n);

??? return __result;

? }

?

? static void deallocate(void* __p, size_t /* __n */)

? {

??? free(__p);

? }

?

? static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz)

? {

??? void* __result = realloc(__p, __new_sz);

??? if (0 == __result) __result = _S_oom_realloc(__p, __new_sz);

??? return __result;

? }

?

? static void (* __set_malloc_handler(void (*__f)()))()

? {

??? void (* __old)() = __malloc_alloc_oom_handler;

??? __malloc_alloc_oom_handler = __f;

??? return(__old);

? }

?

};

?

2.?? 內存分配與釋放

使用mallocrealloc分配內存,對于分配內存異常的處理,模板庫中交給內部的這兩個靜態方法:

_S_oom_malloc

_S_oom_ realloc

?

使用free釋放內存,對于釋放內存來說,是無異常處理的,直接調用free指針,傳入的size_t未使用。

?

3?? 分配異常處理

分配內存的異常處理方法,參考_S_oom_malloc/_S_oom_realloc中的實現

在實現中或者是通過拋出異常,或者是通過執行約定的處理函數(如內存整理函數),然后繼續申請內存。

在下面的函數中,涉及了函數指針:

__malloc_alloc_oom_handler

這個函數指定方法__malloc_alloc_template ::__set_malloc_handler

?

如果這個函數未指定的話,調用異常__THROW_BAD_ALLOC處理

a.?? C++下,拋出std::bad_alloc(),

b.?? C下,向標準輸出中打印并終止程序: fprintf(stderr, "out of memory\n"); exit(1)

?

如果這個函數指定的話,指行這個函數(例如內存整理函數),然后再次申請內存,直到成功申請到后返回申請到的內存地址:

__my_malloc_handler = __malloc_alloc_oom_handler;

(*__my_malloc_handler)();

__result = malloc(__n);

if (__result) return(__result);

?

#ifndef __THROW_BAD_ALLOC

#? if defined(__STL_NO_BAD_ALLOC) || !defined(__STL_USE_EXCEPTIONS)

#??? include <stdio.h>

#??? include <stdlib.h>

#??? define __THROW_BAD_ALLOC fprintf(stderr, "out of memory\n"); exit(1)

#? else /* Standard conforming out-of-memory handling */

#??? include <new>

#??? define __THROW_BAD_ALLOC throw std::bad_alloc()

#? endif

#endif

?

#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG

template <int __inst>

void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;

#endif

?

template <int __inst>

void*

__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n)

{

??? void (* __my_malloc_handler)();

??? void* __result;

?

??? for (;;) {

??????? __my_malloc_handler = __malloc_alloc_oom_handler;

??????? if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; }

??????? (*__my_malloc_handler)();

??????? __result = malloc(__n);

??????? if (__result) return(__result);

??? }

}

?

template <int __inst>

void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n)

{

??? void (* __my_malloc_handler)();

??? void* __result;

?

??? for (;;) {

??????? __my_malloc_handler = __malloc_alloc_oom_handler;

??????? if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; }

??????? (*__my_malloc_handler)();

??????? __result = realloc(__p, __n);

??????? if (__result) return(__result);

??? }

}

?

4.?? 封裝的幾組分配方式

a.?? Simple_alloc,附加了檢查0/NULL的操作

?

template<class _Tp, class _Alloc>

class simple_alloc {

?

public:

??? static _Tp* allocate(size_t __n)

????? { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); }

??? static _Tp* allocate(void)

????? { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }

??? static void deallocate(_Tp* __p, size_t __n)

????? { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }

??? static void deallocate(_Tp* __p)

????? { _Alloc::deallocate(__p, sizeof (_Tp)); }

};

?

b.?? debug_alloc每次分配時,多附加8字節的空間,用于存儲當前分配的size大小。

// Allocator adaptor to check size arguments for debugging.

// Reports errors using assert.? Checking can be disabled with

// NDEBUG, but it's far better to just use the underlying allocator

// instead when no checking is desired.

// There is some evidence that this can confuse Purify.

template <class _Alloc>

class debug_alloc {

?

private:

?

? enum {_S_extra = 8};? // Size of space used to store size.? Note

??????????????????????? // that this must be large enough to preserve

??????????????????????? // alignment.

?

public:

?

? static void* allocate(size_t __n)

? {

??? char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);

??? *(size_t*)__result = __n;

??? return __result + (int) _S_extra;

? }

?

? static void deallocate(void* __p, size_t __n)

? {

??? char* __real_p = (char*)__p - (int) _S_extra;

??? assert(*(size_t*)__real_p == __n);

??? _Alloc::deallocate(__real_p, __n + (int) _S_extra);

? }

?

? static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz)

? {

??? char* __real_p = (char*)__p - (int) _S_extra;

??? assert(*(size_t*)__real_p == __old_sz);

??? char* __result = (char*)

????? _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra,

?????????????????????????????????? __new_sz + (int) _S_extra);

??? *(size_t*)__result = __new_sz;

??? return __result + (int) _S_extra;

? }

?

};

?

?

5.?? 內存分配類allocator/__allocator

allocator分配類使用缺省的分配類(alloc),使用分配類的靜態方法。

__allocator類需要輸入分配類,并對分配類實例化了對像,調用對像的分配方法分配內存。

a)?? allocator

?

// This implements allocators as specified in the C++ standard.?

//

// Note that standard-conforming allocators use many language features

// that are not yet widely implemented.? In particular, they rely on

// member templates, partial specialization, partial ordering of function

// templates, the typename keyword, and the use of the template keyword

// to refer to a template member of a dependent type.

?

#ifdef __STL_USE_STD_ALLOCATORS

?

template <class _Tp>

class allocator {

? typedef alloc _Alloc;????????? // The underlying allocator.

public:

? typedef size_t???? size_type;

? typedef ptrdiff_t? difference_type;

? typedef _Tp*?????? pointer;

? typedef const _Tp* const_pointer;

? typedef _Tp&?????? reference;

? typedef const _Tp& const_reference;

? typedef _Tp??????? value_type;

?

? template <class _Tp1> struct rebind {

??? typedef allocator<_Tp1> other;

? };

?

? allocator() __STL_NOTHROW {}

? allocator(const allocator&) __STL_NOTHROW {}

? template <class _Tp1> allocator(const allocator<_Tp1>&) __STL_NOTHROW {}

? ~allocator() __STL_NOTHROW {}

?

? pointer address(reference __x) const { return &__x; }

? const_pointer address(const_reference __x) const { return &__x; }

?

? // __n is permitted to be 0.? The C++ standard says nothing about what

? // the return value is when __n == 0.

? _Tp* allocate(size_type __n, const void* = 0) {

??? return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)))

??????????????????? : 0;

? }

?

? // __p is not permitted to be a null pointer.

? void deallocate(pointer __p, size_type __n)

??? { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }

?

? size_type max_size() const __STL_NOTHROW

??? { return size_t(-1) / sizeof(_Tp); }

?

? void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }

? void destroy(pointer __p) { __p->~_Tp(); }

};

?

?

b)?? __allocator

可以傳入不同的分配方式,另外實例化了對像,支持對象內記錄分配字節等,屬于對復雜分配方式的支的。

__allocator最大的特點,實例化了分配對像

// Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc)

// into a standard-conforming allocator.?? Note that this adaptor does

// *not* assume that all objects of the underlying alloc class are

// identical, nor does it assume that all of the underlying alloc's

// member functions are static member functions.? Note, also, that

// __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>.

?

template <class _Tp, class _Alloc>

struct __allocator {

? _Alloc __underlying_alloc;

?

? typedef size_t??? size_type;

? typedef ptrdiff_t difference_type;

? typedef _Tp*?????? pointer;

? typedef const _Tp* const_pointer;

? typedef _Tp&?????? reference;

? typedef const _Tp& const_reference;

? typedef _Tp??????? value_type;

?

? template <class _Tp1> struct rebind {

??? typedef __allocator<_Tp1, _Alloc> other;

? };

?

? __allocator() __STL_NOTHROW {}

? __allocator(const __allocator& __a) __STL_NOTHROW

??? : __underlying_alloc(__a.__underlying_alloc) {}

? template <class _Tp1>

? __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW

??? : __underlying_alloc(__a.__underlying_alloc) {}

? ~__allocator() __STL_NOTHROW {}

?

? pointer address(reference __x) const { return &__x; }

? const_pointer address(const_reference __x) const { return &__x; }

?

? // __n is permitted to be 0.

? _Tp* allocate(size_type __n, const void* = 0) {

??? return __n != 0

??????? ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp)))

??????? : 0;

? }

?

? // __p is not permitted to be a null pointer.

? void deallocate(pointer __p, size_type __n)

??? { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }

?

? size_type max_size() const __STL_NOTHROW

??? { return size_t(-1) / sizeof(_Tp); }

?

? void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }

? void destroy(pointer __p) { __p->~_Tp(); }

};

?

?

?

6.?? 內存分配結構體

這個結構體很有意思,

參數一:?_S_instanceless標識包含有allocator_type定義

參數二:?_Alloc_type,簡單分配方式,simple_alloc調用_Alloc的靜態方法進行分配釋放內存

參數三: ?allocator_type,可支持復雜分配方式,實例化了_Alloc對像,使用對象方法分配釋放內存,支持對象內包含分配的總數,或其它附加信息,可以在對像內實現內存池等。

template <class _Tp, class _Alloc>

struct _Alloc_traits<_Tp, debug_alloc<_Alloc> >

{

? static const bool _S_instanceless = true;

? typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type;

? typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type;

};

?

總結

以上是生活随笔為你收集整理的STL内存分配的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。