作者eagle32 (バスケがしたいです)
看板C_and_CPP
標題[問題] 避免碎片化的動態記憶體配置方式
時間Tue Dec 4 15:28:38 2018
大家好. 我對於電腦記憶體的理解不多. 只是常聽說要避免記憶體碎片化.
所以就學了以下語法要一塊連續記憶體去配製一個陣列. 但是當陣列太大時.
譬如50*50*50 的 double array 執行時就發生segmentaion fault. 請大家指教我哪裡做錯想錯了.
謝謝大家.
#include <stdlib.h>
#include <stdio.h>
int main() {
double ***array;
double **ppData;
double *pData;
int l=50;
int m=50;
int n=50;
int i,j,k;
array = (double ***)calloc(l*m*n, l*sizeof(double **) + l*m*sizeof(double *) +
l*m*n*sizeof(double));
ppData = (double **) (array+l);
pData = (double *) (array+l+l*m);
for(i=0; i < l; i++)
{
array[i]=ppData;
ppData+=m;
for(j=0; j < m; j++)
{
array[i][j]=pData;
pData+=n;
}
}
for(i=0; i<l; i++)
for(j=0; j<m; j++)
for(k=0; k<n; k++)
printf("(%d, %d, %d)=%f\n", i,j,k,array[i][j][k]);
free(array);
return 0;
}
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.109.103.228
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1543908520.A.2C3.html
1F:→ school4303: calloc用法是不是錯了 12/04 15:44
3F:→ nh60211as: 第二個argument是每個元素的大小 12/04 15:47
4F:→ nh60211as: 比較像是記憶體不夠用,回傳了NULL POINTER 12/04 15:51
5F:→ sarafciel: 你這個不是50^3,是(50^3)^2 約等於14.5G個element 12/04 17:10
6F:→ sarafciel: 保守點拿32bit機器的4byte指標來算 你要了58G左右 12/04 17:14
7F:→ sarafciel: 咦等等 你最後一個不是指標而是double 那就是116G了XD 12/04 17:27
8F:→ eagle32: 的確我錯用 calloc 了.導致我要了大約126G的記憶體 12/04 21:54
9F:→ poyenc: pData 的初始化也有問題, 只是指標大小相同所以算出來位址 12/04 22:46
10F:→ poyenc: 剛好是對的 12/04 22:46
11F:→ poyenc: 簡單說以一個整數 c 來說, array + c 代表的涵義是從array 12/04 23:02
12F:→ poyenc: 指向的位置開始, 往後算 c 個 sizeof(*array) 物件之後的 12/04 23:02
13F:→ poyenc: 位址, 這裡的 sizeof(*array) == sizeof(double**), 表示 12/04 23:03
14F:→ poyenc: array + c 實際上是在預留 c 個 double** 的空間, 這部分 12/04 23:04
15F:→ poyenc: 沒問題; 但在初始化 pData 的時候你用的方法卻是和 ppData 12/04 23:05
16F:→ poyenc: 一樣, 多預留 l*m 個 double** 空間給 double* 用 12/04 23:06
17F:→ eagle32: 有看過指標指向多維陣列的圖解. 不過一下子找不到了 12/04 23:08
18F:→ eagle32: 像p大說的.我這個部分也理解錯了 12/04 23:09
19F:推 OhNo386: 指標的指標其實很慢,用一維表示二維或多維會快很多 12/08 08:07