Re: [問題] 避免碎片化的動態記憶體配置方式

作者: poyenc (髮箍)   2018-12-04 17:09:10
※ 引述《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 版)
作者: poyenc (髮箍)   2018-12-04 18:14:00
算 a1d 時少加位移, 晚點回家修正 qq
作者: dzwei (Cout<< *p << \n ;)   2018-12-04 18:22:00
typedef好方法給推
作者: eagle32 (バスケがしたいです)   2018-12-04 22:12:00
謝謝分享.
作者: ilikekotomi (Young)   2018-12-05 01:04:00
沒想過這種寫法 感謝分享
作者: friends29 (涼哥哥)   2018-12-06 09:55:00
上色看了好舒服

Links booklink

Contact Us: admin [ a t ] ucptt.com