使用sizeof对malloc struct指针的正确方法是什么?

时间:2015-04-07 08:36:24

标签: c

想象一下,我有以下结构

struct Memory {
    int type;
    int prot;
};

typedef struct Memory *Memory;

我如何使用malloc()初始化它?

Memory mem = malloc(sizeof(Memory));

Memory mem = malloc(sizeof(struct Memory));

分配它的正确方法是什么?

3 个答案:

答案 0 :(得分:9)

您的结构声明有点混乱,并且typedef在许多级别上都是错误的。以下是我的建议:

//typedef + decl in one
typedef struct _memory {
    int type;
    int prot;
} Memory;

然后像这样分配:

Memory *mem = malloc(sizeof *mem);

如此阅读malloc来电:"分配存储mem指向" 的任何类型所需的内存量。如果您将Memory *mem更改为Memory **mem,它将分配4或8个字节(取决于平台),因为现在它可能会分配8个字节,具体取决于大小int的编译器以及编译器如何填充结构check wiki for more details and examples

使用sizeof *<the-pointer>通常被认为是分配内存的更好方法,但如果您愿意,可以写:

Memory *mem = malloc(sizeof(Memory));
Memory *mem = malloc(sizeof(struct _memory));

他们都做同样的事情。请注意,如果你typedef结构,那可能是因为你想要抽象某些东西的内部运作,并且想要编写各种各样的API。在这种情况下,您应该尽可能不鼓励使用struct _memory,无论如何都支持Memory*<the-pointer>

如果你想要typedef一个指针,那么你可以这样写:

typedef struct _memory {
    int type;
    int prot;
} *Memory_p;

在这种情况下:

Memory_p mem = malloc(sizeof *mem);

可能似乎反直觉,但是是正确的,因为:

Memory_p mem = malloc(sizeof(struct _memory));

但是这个:

Memory_p mem = malloc(sizeof(Memory_p));

是错误的(它不会分配结构所需的内存,而是存储指向它的指针的内存)。

这可能是个人偏好的问题,但我个人认为typedef模糊了某些事情。在许多情况下,这是更好的(即FILE*),但是一旦API开始隐藏你正在使用指针的事实,我开始担心一点。它往往会使代码更难以阅读,调试和记录......

想想这样:

int *pointer, stack;

*运算符修改给定类型的变量,指针typedef同时执行。这只是我的观点,我确信有很多程序员比我使用指针类型def技术要熟练得多。
但是大多数时候,指针typedef都伴随着自定义分配器函数或宏,所以你不必编写奇怪的语句,如Memory_p mem = malloc(sizeof *mem);,而是你可以写ALLOC_MEM_P(mem, 1);,可以定义为:

#define ALLOC_MEM_P(var_name, count) Memory_p var_name = malloc(count * sizeof *var_name)

或其他什么

答案 1 :(得分:2)

两个

 typedef struct Memory * Memory;

 Memory mem = malloc (sizeof (Memory));

错了。正确的方法是:

typedef struct memory
{
     int type;
     int prot;
} *MEMPTR;

struct memory
{
     int type;
     int prot;
};

typedef struct memory *MEMPTR;

结构的名称应该与指向它的指针的名称不同。

答案 2 :(得分:2)

这种结构

struct {
    int type;
    int prot;
} Memory;

定义一个名为Memory的对象,其类型为未命名的结构。

因此下一个建筑

typedef struct Memory *Memory;

定义1)一个新类型struct Memory,与上面的定义和名称Memory没什么共同之处。 2)另一个新类型名称Memory,它指向struct Memory

如果两个构造都存在于同一个编译单元中,那么编译器将发出错误,因为typedef声明中的名称Memory(指针名称)会尝试重新声明未命名类型的对象具有相同名称Memory

的结构

我认为你的意思是以下

typedef struct Memory {
    int type;
    int prot;
} Memory;

在这种情况下,您可以使用malloc的两个记录,如

Memory *mem = malloc( sizeof( Memory ) );

struct Memory *mem = malloc( sizeof( struct Memory ) );

Memory *mem = malloc( sizeof( struct Memory ) );

struct Memory *mem = malloc( sizeof( Memory ) );

因为现在两个标识符Memory位于两个不同的名称空间中,第一个用于标记struct,第二个用于没有标记结构。