Re: [問題] C-malloc
※ 引述《tropical72 (藍影)》之銘言:
: 手邊有份案子,初始化時 malloc 動作非常頻繁,
: 寫了副函式覺得很奇怪,很怕會出包,請教下列動作是否正常
: #define X 10
: #define Y 20
: void** Malloc2Dim(unsigned x, unsigned y)
: {
: unsigned i;
: void **ptr= (void**)malloc(sizeof(void*) * x);
: for(i=0; i!=x; ++i) ptr[i] = (void*)malloc(sizeof(void) * y);
×
: return ptr;
: }
根據 C99, 6.5.3.4
2 The sizeof operator yields the size (in bytes) of its operand,
which may be an expression or the parenthesized name of a type. The
size is determined from the type of the operand...(以下略)
後面倒沒有對於 sizeof void 的規定...gcc 會給 warning, 回傳結果為 1
[Warning] invalid application of 'sizeof' to a void type
: double **p = (double**)Malloc2Dim(X, Y);
: for(i=0; i!=X; ++i) memset(p[i], 0, sizeof(double)*Y);
: 問題1:sizeof(void*), sizeof(void), vc2008(.c) 是合法的,
: 但怎麼想都有點不對, 因不能保證 sizeof(void) = sizeof(double)
你想的沒錯, 這是不具可攜性的寫法
: 問題2 : 最下面那個 for loop, 有沒有辦法更快?直接用一個 memset 就過去了?
: 謝謝各位不吝指教!
有, 就像我之前貼的程式碼一樣
typedef double my_float;
my_float** Malloc2Dim(size_t x, size_t y)
{
my_float **ptr= (my_float**)malloc(sizeof(my_float*) * x );
my_float *trunk = (my_float*)malloc(sizeof(my_float) * x * y );
for( size_t i = 0; i != x; ++i )
{
ptr[i] = trunk;
trunk += y;
}
return ptr;
}
-
my_float **p = Malloc2Dim(X, Y);
memset( *p, 0, sizeof(my_float) * x * y );
釋放也很簡單
free( *p );
free( p );
--
◢████ ◢█ ◢██◣ ◢█ ◢███ ◢█ T-ara版怎麼去
████◤ ██ ◢██◣█ ██ ████ ██ s ~> T-ara
█/███ ██ ██ ██ █/█ ◢███ █/█ 歡迎您的光臨
████◤ ██ ██ ██ ██◤ ███◤ ██◤ 恩靜、智妍、孝敏
█/███ ██ █/██◤ ██ █/██ ██ 素妍、居麗、寶藍
████◤ █◤ ◥██◤ █◤ ████◤█◤ 花英 ψmakigoto123
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.197.115
推
04/07 20:22, , 1F
04/07 20:22, 1F
= ="
→
04/07 20:46, , 2F
04/07 20:46, 2F
→
04/07 20:46, , 3F
04/07 20:46, 3F
這樣嗎?
void** Malloc2Dim(size_t x, size_t y, size_t element_size)
{
void **ptr= (void**)malloc(sizeof(void*) * x );
char *trunk = (char*)malloc(element_size * x * y );
for( size_t i = 0; i != x; ++i )
{
ptr[ i ] = trunk;
trunk += (element_size * y);
}
return ptr;
}
-
double** p = (double**)Malloc2Dim( X, Y, sizeof(double) );
如你所見, 會變得比較麻煩
推
04/07 21:03, , 4F
04/07 21:03, 4F
推
04/07 21:23, , 5F
04/07 21:23, 5F
推
04/07 21:30, , 6F
04/07 21:30, 6F
推
04/07 21:33, , 7F
04/07 21:33, 7F
不行, 指標的移動距離必須根據指到的型別來決定, 除非你硬把它轉成
intptr_t/uintptr_t 來做運算, 不然在 gcc 上會得到下面的警告:
void *p = 0;
p += 10;
[Warning] pointer of type 'void *' used in arithmetic
運算後的數值則是
0 + 10 * sizeof(void)
這就跟之前遇到的問題一樣了
※ 編輯: loveme00835 來自: 140.121.197.115 (04/07 21:49)
推
04/07 22:22, , 8F
04/07 22:22, 8F
討論串 (同標題文章)