2012-12-21 116 views
0

請考慮下面的代碼:爲什麼malloc不無鑄造工作?

#include "stdafx.h" 
#include <stdio.h> 
#include <assert.h> 
#include <stdlib.h> 
#include <string.h> 

struct Person { 
    char *name; 
    int age; 
    int height; 
    int weight; 
}; 

struct Person *Person_create(char *name, int age, int height, int weight) 
{ 
    struct Person *who = (struct Person*) malloc(sizeof(struct Person)); 
    assert(who != NULL); 

    who->name = strdup(name); 
    who->age = age; 
    who->height = height; 
    who->weight = weight; 

    return who; 
} 

好奇線

struct Person *who = (struct Person*) malloc(sizeof(struct Person)); 

我上網搜索了一下的malloc()函數的用法。其中約一半是用鑄造書寫的,其他則不是。在VS2010,沒有(struct Person*)投一個錯誤出現了:

1>c:\users\juhyunlove\documents\visual studio 2010\projects\learnc\struct\struct\struct.cpp(19): error C2440: 'initializing' : cannot convert from 'void *' to 'Person *' 
1>   Conversion from 'void*' to pointer to non-'void' requires an explicit cast 

那麼,什麼是創建一個指針和內存分配給它一個適當的方式?

+1

如果你寫C代碼,你應該總是** **編譯C和你**絕不**投的malloc'的返回值()'。 – 2012-12-21 17:36:55

+0

重命名'struct.cpp'爲'struct.c'使Visual Studio中挖掘其令人難以置信的過時的C編譯器。 – Cubbi

+0

BTW,不要'assert'的返回值'malloc'。用if語句檢查它的返回值。 – netcoder

回答

12

由於您使用的是C++編譯器。

鑄造malloc(假定類型不是void *)在C++中是必需的。在C,它不是必需的,它甚至建議不要投malloc

在C有從void *到所有對象指針類型分配期間的隱式轉換。

void *p = NULL; 
int *q = p; // valid in C, invalid in C++ 
+0

......和+1,當然。 – 2012-12-21 17:37:59

1

如果重命名從struct.cpp您的文件,以struct.c,編譯器會做你期望的C編譯器的事,而不是做一個C++編譯器應該做些什麼(如上所述)是什麼。 Visual Studio中附帶了一個編譯器,可以做C和C++,所以它只是當你創建正確命名的文件的情況。

我不確定在Visual Studio中重命名文件是否足夠,或者如果必須添加一個名爲struct.c的新文件,請將現有文件中的內容複製到該文件中,然後刪除原始結構。 CPP。後者絕對有效。