Re: [問題] 避免碎片化的動態記憶體配置方式
※ 引述《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
→
12/04 18:14,
7年前
, 1F
12/04 18:14, 1F
推
12/04 18:22,
7年前
, 2F
12/04 18:22, 2F
※ 編輯: poyenc (123.193.76.85), 12/04/2018 20:03:42
推
12/04 22:12,
7年前
, 3F
12/04 22:12, 3F
推
12/05 01:04,
7年前
, 4F
12/05 01:04, 4F
推
12/06 09:55,
7年前
, 5F
12/06 09:55, 5F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章