1

请考虑以下代码:

#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

那么创建指针并为其分配内存的正确方法是什么?

4

2 回答 2

14

因为您使用的是 C++ 编译器。

C++ 中需要强制转换malloc(假设类型不是)。void *在 C 中,它不是必需的,甚至建议不要强制转换malloc

void *在 C 中,在赋值期间存在从到所有对象指针类型的隐式转换。

void *p = NULL;
int *q = p;  // valid in C, invalid in C++
于 2012-12-21T17:35:55.580 回答
1

如果您将文件从 struct.cpp 重命名为 struct.c,编译器将执行您期望 C 编译器执行的操作,而不是执行 C++ 编译器应该执行的操作(如上所述)。Visual Studio 带有一个可以同时执行 C 和 C++ 的编译器,因此它只是在创建文件时正确命名文件的情况。

我不确定在 Visual Studio 中重命名文件是否足够,或者是否必须添加一个名为 struct.c 的新文件,将现有文件中的内容复制到其中,然后删除原始 struct.cpp。后者绝对有效。

于 2012-12-21T20:27:40.990 回答