作者poyenc (髮箍)
看板C_and_CPP
標題Re: [問題] 避免碎片化的動態記憶體配置方式
時間Tue Dec 4 17:09:10 2018
※ 引述《eagle32 (バスケがしたいです)》之銘言:
: 大家好. 我對於電腦記憶體的理解不多. 只是常聽說要避免記憶體碎片化.
: 所以就學了以下語法要一塊連續記憶體去配製一個陣列. 但是當陣列太大時.
: 譬如50*50*50 的 double array 執行時就發生segmentaion fault. 請大家指教我哪裡做錯想錯了.
適當地
抽象化可以幫助思考/除錯, 這時候
typedef 是你的好朋友
一次只思考一個層級, 如果要配置大小為
10 的
一維陣列, 我們可
以這樣寫:
typedef double value_t;
typedef value_t*
array1d;
array1d a1d = (array1d) calloc(
10,
sizeof(
value_t));
一維陣列的每個元素的型別是
value_t. 如果要配置
二維陣列呢?
你可以依樣畫葫蘆:
二維陣列的每個元素型別是
一維陣列
typedef array1d*
array2d;
array2d a2d = (array2d) calloc(
10,
sizeof(
array1d));
這個概念持續發展下去, 不管是三維、四維還是更多維陣列你都有
辦法作出來, 先分享不連續配置的範例如下:
https://godbolt.org/z/DHoUSD
calloc() 有個問題是: 它是用來配置
同樣型別的物件. 以你的案
例想把
array1d、
array2d 不同型別物件放一起的話, 就需要特別
注意指標位移的計算; 不過這邊為了簡化, 可以先配置好一塊
char 陣列, 位址計算就會相對容易, 後面的程式碼不需大改:
const size_t total_size = l *
sizeof(
array2d)
+ (l * m) *
sizeof(
array1d)
+ (l * m * n) *
sizeof(
value_t)
;
char *buffer = (
char*) calloc(total_size,
1);
array3d a3d = (array3d) buffer;
array2d a2d = (array2d) (
a3d + l);
array1d a1d = (array1d) (
a2d + l * m);
如果你還是比較喜歡一堆星星(*) 的寫法, 可以把前面用
typedef
創出來的
array1d、
array2d 等型別給取代掉. 最後連續配置的範
例如下:
https://godbolt.org/z/01tokn
https://godbolt.org/z/Oq8oRX (無
typedef 版)
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.76.85
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1543914554.A.A94.html
→ poyenc: 算 a1d 時少加位移, 晚點回家修正 qq 12/04 18:14
推 dzwei: typedef好方法給推 12/04 18:22
※ 編輯: poyenc (123.193.76.85), 12/04/2018 20:03:42
推 eagle32: 謝謝分享. 12/04 22:12
推 ilikekotomi: 沒想過這種寫法 感謝分享 12/05 01:04
推 friends29: 上色看了好舒服 12/06 09:55