/*
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 外部鏈結性,內部鏈結性和無鏈結性 所有靜態變數都有下面的兩個初始...
總結之 記憶體管理
一 記憶體管理的原因 本質原因 因為物件和其他資料型別在系統中的儲存空間不一樣,其它區域性變數主要存放於棧中,而物件儲存於堆中,當 塊結束時這個 塊中涉及的所有區域性變數會被 指向物件的指標也被 此時物件已經沒有指標指向,但依然存在於記憶體中,造成記憶體洩露。二 記憶體管理 所謂記憶體管理,就是對記...