2012-03-23 133 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))) 
相关问题