看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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
tropical72:我看到神之手向我伸援了..謝謝loveme !!! 04/07 20:22
= ="
tropical72:我突然想問,如果在引數裡面名放一個 sizeof(type); 04/07 20:46
tropical72:是否就能夠不用 typedef 避開這個問題了? 04/07 20:46
這樣嗎? 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) ); 如你所見, 會變得比較麻煩
tropical72:謝謝神之手再次降臨!再次感謝!! 04/07 21:03
xatier:loveme大必推! 04/07 21:23
cole945:方陣的話有trunk就夠了呀@@ my_float[x][y]算一下就知道了 04/07 21:30
tropical72:第二段的 trunk 可以改成是 void* 嗎? 04/07 21:33
不行, 指標的移動距離必須根據指到的型別來決定, 除非你硬把它轉成 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)
tropical72:真是感謝,受用無窮。 04/07 22:22