作者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://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1543914554.A.A94.html
1F:→ poyenc: 算 a1d 时少加位移, 晚点回家修正 qq 12/04 18:14
2F:推 dzwei: typedef好方法给推 12/04 18:22
※ 编辑: poyenc (123.193.76.85), 12/04/2018 20:03:42
3F:推 eagle32: 谢谢分享. 12/04 22:12
4F:推 ilikekotomi: 没想过这种写法 感谢分享 12/05 01:04
5F:推 friends29: 上色看了好舒服 12/06 09:55