2012-03-23 135 views
1

我有一個類似於下面的C程序。我正在嘗試在malloc之上用int myAlloc()的簽名編寫包裝。這個包裝器應該在成功分配內存時返回1,如果內存分配失敗,則返回0。不兼容的指針類型警告

#include <stdio.h> 
#include <stdlib.h> 

int myAlloc(void **ptr, int size) 
{ 
    *ptr = malloc(size); 

    if (!ptr) 
     return 0; 
    else 
     return 1; 
} 

void main() 
{ 
    int *p = NULL; 
    myAlloc(&p, sizeof(int)); 
    printf("%d\n", *p); 
} 

當我編譯這個時,我得到一個警告說「不兼容的指針類型」。我怎樣才能使用任何可能的指針類型調用此函數而不接收警告?

是否可以從實際的函數調用中移除鑄造操作?

更新

我找到了答案。下面是更正後的代碼:

#include <stdio.h> 
#include <stdlib.h> 

int myAlloc(void *ptr,int size) 
{ 
    *(void **)ptr = malloc(size); 

    if (!ptr) 
     return 0; 
    else 
     return 1; 

} 

int main() 
{ 
    int *p = NULL; 
    myAlloc(&p, sizeof(int)); 
    *p = 5; 
    printf("%d\n", *p); 

    return 1; 
} 
+0

這似乎不是標準C,或C++,作爲主要不返回無效。 – 2012-03-23 13:30:49

+0

@ RichardJ.RossIII你錯了。閱讀[this](http://stackoverflow.com/questions/5296163/why-is-the-type-of-the-main-function-in-c-and-c-left-to-the-user-to -define/5296593#5296593)。 – Lundin 2012-03-23 13:31:53

+1

@Lundin我已經讀過了,我的觀點依然存在。我不相信這是在獨立的環境或託管環境中。 – 2012-03-23 13:33:24

回答

0
#include <stdio.h> 
#include <stdlib.h> 

int myAlloc(void *ptr,int size) 
{ 
    *(void **)ptr=malloc(size); 
    if(!ptr) return 0; 
    else return 1; 

} 

int main() 
{ 
    int *p=NULL; 
    myAlloc(&p,sizeof(int)); 
    *p=5; 
    printf("%d\n",*p); 
    return 1; 
} 
-1

p是類型int*,而你的函數接受void**

myAlloc((void **)&p,sizeof(int)); 
-1

按照myAlloc的簽名,你應該myAlloc((void**)&p,sizeof(int)),因爲P是int*(PTR爲int),而不是void*(PTR作廢)調用它。

-2

OT:代碼中存在一個錯誤。你可能想:

if(!(*ptr)) return 0; 
0

實際的錯誤,我看 - 這可能不是你的一樣;我們無法知道,因爲你忽略了向我們展示了實際輸出 - 看起來是這樣的:

src.c: In function ‘main’: 
src.c:15:17: warning: passing argument 1 of ‘myAlloc’ from incompatible pointer type [enabled by default] 
src.c:4:5: note: expected ‘void **’ but argument is of type ‘int **’ 

你通過你的myAlloc功能的int **變量,但你的函數被寫入接受void **變量。您可以在函數調用這樣的轉換指針類型:

myAlloc((void **)&p,sizeof(int)); 

現在它編譯沒有警告。

您可能需要閱讀The C Bookpointers部分,特別是第5.3.5節,其中明確說明了此處提出的一些問題。

+0

它不會發出警告,但可能會崩潰。考慮一個具有'sizeof(int *) asaelr 2012-03-23 14:41:53

+0

的平臺。這就是我指出C書第5.3.5節的原因之一。如果你看看你會看到它討論這個。 – larsks 2012-03-23 15:22:25

3

你的函數,myMalloc需要一個指針的指針無效,或者void**你傳遞一個指針的地址爲int,或int**

你需要投你通過爲無效例如指針

myAlloc((void**)&p,sizeof(int)); 
+0

是的,這將解決。但是,是否有可能從實際的函數調用中刪除投射操作? – user995487 2012-03-23 14:57:01

+0

由於違反'* ptr = malloc(size)'(C99 6.5§7) – Christoph 2012-03-23 15:34:09

+1

處的嚴格別名,導致未定義的行爲我不這麼認爲......模板會讓它變成輕而易舉,但是IIRC C沒有任何東西模板。其他方面,所有類型都是超負荷的,但那樣會變得混亂 – thecoshman 2012-03-23 15:35:46

0

這可能看起來學術有趣,但沒有在包裝的內部代碼做同樣的boolean類型的檢查?

void *ptr; 
if((ptr = malloc(1000))) 
{ 
    /* Do stuff with ptr */ 
} 
else 
{ 
    /* throw a tantrum */ 
} 

你是否真的需要帶有額外參數複雜度的int返回碼?

0

在C中,對於通用指針有一個void*類型,但是沒有指向指針的通用指針的類型。更糟的是,不同類型的指針的大小可能不相等。因此,如果你的函數不知道它應該分配什麼類型的指針,它不能只是「把數據放在地址中」,因爲右指針的大小可能與它指定的指針大小不同。

例如,如果sizeof(int*)<sizeof(void*),您的代碼可能會崩潰(並且是UB)。

因此,我認爲這是不可能寫你想要的包裝。

0

在符合標準的C中沒有辦法編寫這樣的函數,因爲int *void *是不兼容的類型。

A(大部分)等效宏定義可能看起來像這樣:

#define myAlloc(PTR, SIZE) (!!(PTR = malloc(SIZE))) 
相關問題