BOOST C 之記憶體管理

2021-10-07 13:14:03 字數 4439 閱讀 5609

/*

raii(resource acquisition is initialzation) 機制,在使用資源的類的建構函式中申請資源,然後使用,最後在

析構函式中釋放資源。

*/#include

#include

#include

#include

using

namespace std;

// auto_ptr 測試

void

auto_ptr_test()

/* boost.smart_ptr 提供了六種智慧型指標

scoped_ptr,scoped_array,shared_ptr,shared_array,weak_ptr和intrusive_ptr.

命名空間:boost

標頭檔案:#include */

#include

using

namespace boost;

/* scoped_ptr:

類似 auto_ptr,包裝了 new 操作符在堆上分配的動態物件,能夠保證建立的物件在任何時候都

可以被正確的刪除。但該指標不可轉讓,一旦獲取物件的管理權,就無法取回。

該指標只能在本作用域使用,不可被轉讓。

1. 建構函式接收乙個型別為 t* 的指標,建立乙個scoped_ptr物件,並在

內部儲存指標引數p,p必須是乙個new表示式動態分配的結果,或者是空

指標。scoped_ptr物件的生命週期結束時,析構函式自動銷毀儲存的指標。

2. 拷貝函式和賦值操作符都是私有的,禁止智慧型指標的複製。使其不可轉讓。

3. reset成員函式功能為重置scoped_ptr,刪除原來儲存的指標,然後儲存新

的指標。一般少用。

4. operator*(),operator->()過載了解引用和箭頭操作符,使類可以像指標

一樣使用。如果是空指標則行為未定義。

5. 不支援比較操作。提供乙個可以在bool語境中自動轉換成bool值的功能,

用來測試指標是否有效,代替與空指標的比較操作。

6. get()成員函式,返回內部儲存的原始指標。注意不可對這個原始指標進行

delete操作,否則類在析構時會發生未定義的行為。

7. 與 auto_ptr 的區別:

auto_ptr 所有權可轉移,但易出錯。

scoped_ptr 拒絕轉移所有權。

*/void

scoped_ptr_test()

}/*scoped_array:指向陣列的智慧型指標,包裝了new 操作符。介面與scoped_ptr幾乎相同。

1. 建構函式接收的指標必須是new的結果;

2. 沒有*和->操作符,因為它不是普通指標;

3. 析構呼叫delete;

4. 提供opertor操作符過載,可以像普通陣列一樣用下標訪問元素;

5. 沒有begin(),end()等類似容器的迭代器操作函式;

6. 沒有特殊要求的情況慎用,最好用vector替代。

*/void

scoped_array_test()

/* shared_ptr:最有價值,最重要,最有用。

包裝了new操作符在堆上分配動態物件,實現的是引用計數形的智慧型指標,

可以自由拷貝和賦值,任意地方共享,當引用計數為0即沒有**使用它

時,刪除分配的物件,可以安全的放到標準容器中。相互間可以進行比較

操作。基本資訊:

1. 無參的 shared_ptr() 建立乙個持有空指標的shared_ptr;

2. shared_ptr(y *p):獲得指向型別t的指標p的管理權,引用計數+1,要求

y型別能夠轉換成t型別。

3. shared_ptr(shared_ptr const &r):從另乙個shared_ptr獲得指標的管理

權,引用計數+1,兩個指標管理權共享。

4. shared_ptr(std::auto_ptr&r):從auto_ptr獲得指標管理權,引用計數

+1,auto_ptr 失去管理權。

5. operator= 賦值操作符可以從另乙個shared_ptr或者auto_ptr獲得指標的管

理權。operator《輸出內部指標值。

6. shared_ptr(y* p,d d)行為類似shared_ptr(y* p),但使用了引數d指定了析

構時的定製刪除器,而非簡單的delete。

7. 提供兩個函式檢查引用計數:

unique(): shared_ptr是指標的唯一所有者時返回true;

use_count():返回當前指標的引用計數,效率低,不可靠,可用於除錯。

8. 支援比較運算,測試兩個shared_ptr是否相等。支援operator《比較大小,但

不支援除operator《以外的比較操作,可用於標準關聯容器(map和set)。

9. 轉型函式:static_pointer_cast(),const_pointer_cast(),

dynamic_pointer_cast()。

定製刪除器:

shared_ptr(y* p,d d)來構造,析構時呼叫函式d。

例如:假設一組操作socket的函式,使用乙個socket_t類:

class socket_t;

socket_t *open_socket()

其他:包裝成員函式,延時釋放等。

shared_array: new操作符分配記憶體,類似scoped_array

*///用法:**示例

class

shared

void

print()

};void

print_func

(boost::shared_ptr<

int>p)

void

shared_ptr_test()

#include

//make_shared() 消除顯式的new呼叫

void

make_shared_test()

cout << endl;}/*

weak_ptr: 配合 shared_ptr 使用,更像是乙個助手而非智慧型指標,不具備普通指標的行為。

沒有過載operator* 和->。最大的作用在於協助 shared_ptr工作,以旁觀者的角

色觀測資源的使用情況。

1. weak_ptr 可以從乙個shared_ptr或者乙個weak_ptr物件構造,獲得資源的觀測權,

weak_ptr 沒有共享資源,其構造與析構不會引起指標引用計數的變化。

2. 使用weak_ptr 的成員函式 use_count()可以觀測資源的引用計數。

3. expired()函式功能與 use_count() == 0 等價,但效率更高,標識被觀測資源不

存在。4. 成員函式 lock() 從被觀測的shared_ptr獲得乙個可用的shared_ptr物件,從而

操作資源。當expired() == true 時,返回儲存空指標的shared_ptr。

*/void

weak_ptr_test()

assert(1

== wp.

use_count()

);}/*

記憶體池:

pool,object_pool,單例記憶體池singleton_pool,pool_alloc 可用於標準庫,一般不用除非特殊需求

標頭檔案:

#include */

#include

#include

#include

//pool 只能作為普通資料型別 int,double 等的記憶體池,不可應用於複雜的類和物件

struct pool_tag

;typedef singleton_poolsizeof

(int

)> sp1;

void

pool_test()

assert

(p1.

is_from

(p))

; p1.

free

(p);

//連續分配大量記憶體

for(

int i =

0; i <

100; i++

)//單例記憶體池,執行緒安全的

int*p_singleton =

(int

*)sp1::

malloc()

;assert

(sp1::

is_from

(p_singleton));

//釋放左右未被分配的記憶體,已分配的記憶體直到整個程式結束才會釋放。

sp1::

release_memory()

;}//object_pool 測試程式

struct demo_class};

void

object_pool_test()

}

記憶體管理之記憶體定址

記憶體定址 三種記憶體位址 邏輯位址 logical address 包含機器語言指令中用來指定乙個運算元或一條指令的位址 線性位址 linear address 線性位址也稱為虛擬位址 virtual address 實體地址 physical address 用於記憶體晶元級記憶體單元定址,他們...

c 之記憶體管理

c 使用3 種不同解決方案儲存資料,區別是資料保留在記憶體中的時間 兩種儲存持續性為自動 自動變數和暫存器變數 register 沒有記憶體位址 堆疊 在函式外定義的變數和使用關鍵字static定義的變數的儲存持續性都為靜態.分為 3 外部鏈結性,內部鏈結性和無鏈結性 所有靜態變數都有下面的兩個初始...

總結之 記憶體管理

一 記憶體管理的原因 本質原因 因為物件和其他資料型別在系統中的儲存空間不一樣,其它區域性變數主要存放於棧中,而物件儲存於堆中,當 塊結束時這個 塊中涉及的所有區域性變數會被 指向物件的指標也被 此時物件已經沒有指標指向,但依然存在於記憶體中,造成記憶體洩露。二 記憶體管理 所謂記憶體管理,就是對記...