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

moe*_*eth 0 c

想象一下,我有以下结构

struct Memory {
    int type;
    int prot;
};

typedef struct Memory *Memory;
Run Code Online (Sandbox Code Playgroud)

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

Memory mem = malloc(sizeof(Memory));
Run Code Online (Sandbox Code Playgroud)

要么

Memory mem = malloc(sizeof(struct Memory));
Run Code Online (Sandbox Code Playgroud)

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

Eli*_*gem 9

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

//typedef + decl in one
typedef struct _memory {
    int type;
    int prot;
} Memory;
Run Code Online (Sandbox Code Playgroud)

然后像这样分配:

Memory *mem = malloc(sizeof *mem);
Run Code Online (Sandbox Code Playgroud)

malloc像这样读取调用:"分配存储mem指向的任何类型所需的内存量".如果Memory *mem改为Memory **mem,它将分配4或8个字节(取决于平台),因为它现在可能会分配8个字节,具体取决于int编译器填充struct 检查wiki的大小和方式以获取更多详细信息,例子.

使用sizeof *<the-pointer>通常被认为是分配内存的更好方法,但是你想要的,你可以写:

Memory *mem = malloc(sizeof(Memory));
Memory *mem = malloc(sizeof(struct _memory));
Run Code Online (Sandbox Code Playgroud)

他们都做同样的事情.请注意,如果你typedef是一个结构,那可能是因为你想要抽象某些东西的内部运作,并且想要编写各种各样的API.在这种情况下,你应该鼓励使用struct _memory尽可能多的,赞成Memory*<the-pointer>不管怎么说

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

typedef struct _memory {
    int type;
    int prot;
} *Memory_p;
Run Code Online (Sandbox Code Playgroud)

在这种情况下:

Memory_p mem = malloc(sizeof *mem);
Run Code Online (Sandbox Code Playgroud)

可能看起来反直觉,但是是正确的,因为:

Memory_p mem = malloc(sizeof(struct _memory));
Run Code Online (Sandbox Code Playgroud)

但是这个:

Memory_p mem = malloc(sizeof(Memory_p));
Run Code Online (Sandbox Code Playgroud)

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

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

试试这样:

int *pointer, stack;
Run Code Online (Sandbox Code Playgroud)

*操作者修改一个给定的类型的变量,指针的typedef确实两者.这只是我的观点,我确信有许多程序员比我使用指针typedef技术要熟练得多.
但是大多数情况下,指针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)
Run Code Online (Sandbox Code Playgroud)

或者其他的东西