使用malloc()和sizeof()在堆上创建结构

时间:2010-12-23 14:55:44

标签: c++

我正在尝试使用malloc()和sizeof()在堆上创建结构。这是我的代码:

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

struct Employee
{
    char first[21];
    char last[21];
    char title[21];
    int salary;
};


struct Employee* createEmployee(char* first, char* last, char* title, int salary) // Creates a struct Employee object on the heap.
{
    struct Employee* p = malloc(sizeof(struct Employee)); 

    if (p != NULL)
    {
        strcpy(p->first, first);
        strcpy(p->last, last);
        strcpy(p->title, title);
        p->salary, salary;
    }
    return p;

}

没有我的编译器(Visual C ++)告诉我,行struct Employee* p = malloc(sizeof(struct Employee));无法将类型“void *”转换为“Employee *”类型。我不知道这里有什么问题。看起来好像struct Employee是一个空洞,但我不明白为什么......

5 个答案:

答案 0 :(得分:13)

在C ++中(因为您使用Visual C ++进行编译),您必须显式转换malloc返回的指针:

struct Employee* p = (struct Employee*) malloc(sizeof(struct Employee));

答案 1 :(得分:11)

使用malloc的最佳做法:

struct Employee *p = malloc(sizeof *p); 

你还需要修复你的IDE /编译器,告诉你你正在编写C而不是C ++,因为它太破碎了,无法自己解决这个问题......

由于有些人似乎对这个答案不满意(并且我对其他答案的反对),我想我应该解释为什么解决这个问题并不好。

在C中,强制转换malloc的返回值是有害的,因为如果忘记包含stdlib.h或其他原型malloc,它会隐藏警告。它还使您的代码难以维护;如果需要更改p的类型,那么演员的所有答案都需要进行3次更改,而我的答案只需要在一个地方进行更改。最后,新的C程序员在看到编译器警告或错误时不应该养成使用强制转换的坏习惯。这通常只会掩盖错误。正确的代码几乎从不需要强制转换,它们的使用应被视为代码气味

答案 2 :(得分:1)

您应该将malloc的结果强制转换为您正在使用的指针类型。

struct Employee* p = (struct Employee*)malloc(sizeof(struct Employee)); 

malloc将始终以(void *)的形式返回内存块。由你来告诉编译器内存是什么类型的chunck。

答案 3 :(得分:1)

如果您要编译为C代码,那么该行应该有效。

但在C ++中,从void*Employee*的转换无效。

该文件名为something.c吗?是否有可以更改的编译器选项?

如果必须使用C ++编译器,可以通过添加显式强制转换来解决此问题:

struct Employee* p = (struct Employee*)malloc(sizeof(struct Employee));

答案 4 :(得分:0)

malloc返回的值为void*。您要分配给p的值必须是Employee*类型。在C ++中(与C相反),没有从void*到另一个指针类型的隐式转换。因此,您需要明确执行转换:

struct Employee* p = reinterpret_cast<Employee*>(malloc(sizeof(struct Employee)));