在 C 中为结构体分配内存时,哪项是正确的

发布于 2024-12-03 22:27:30 字数 399 浏览 1 评论 0原文

假设我们有一个简单的结构,例如:

typedef struct
{
    int d1;
    int d2;
    float f1;
}Type;

为它的新实例分配内存时哪个是正确的:

This:

// sizeof *t == sizeof(Type) ( gcc prints 12 bytes)
Type *t = malloc(sizeof *t); 

或:

// sizeof pointer always == 4 (in my case also on gcc)
Type *t = malloc(sizeof(t)); 

哪个是正确的?

Assuming we have a simple struct like:

typedef struct
{
    int d1;
    int d2;
    float f1;
}Type;

Which is the correct when allocate memory for a new instance of it:

This:

// sizeof *t == sizeof(Type) ( gcc prints 12 bytes)
Type *t = malloc(sizeof *t); 

or:

// sizeof pointer always == 4 (in my case also on gcc)
Type *t = malloc(sizeof(t)); 

Which is the correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

吾家有女初长成 2024-12-10 22:27:30

这是正确的方法:

Type *t = malloc(sizeof *t); 

为什么这是正确的?

因为您正确分配了足够大的大小来容纳结构。 *t 指向类型 Type


这是不正确的方法:

Type *t = malloc(sizeof(t)); 

为什么这是不正确的?

sizeof(t) 返回指针的大小而不是实际类型(即:不是结构的大小)。
您需要分配足够大的大小来容纳结构,而不是大小等于指向结构的指针。

请注意,指向 Any 类型的指针的大小在系统上是相同的。


为什么第一种方法更好?
使用第一种方法,当您更改 Type 时,malloc 会自动将大小更改为正确的值,与其他方法不同,您不必显式执行此操作。

此外,编写 malloc 调用的重要部分是找到需要传递的正确大小。执行此操作的最佳方法是不要查看任何地方(因为这就是我们犯错误的时候),而只查看此 malloc 语句的左侧。由于在本例中为 t,因此正确的大小将为 sizeof(*t)

如何标准化malloc的使用?

使用上述正确方法,有一个问题,如果我们想要malloc30个元素。那么我们的 malloc 表达式就变成:

t = (T *) malloc(30 * sizeof (*T));

这不是编写 malloc 表达式的首选方式,因为输入数字 30 可能会出错。在 malloc 参数中。我们想要的是 - 无论需要多少元素,malloc 参数都应该始终是标准的 sizeof(*x) 或类似的东西。

这里有一个例子:

假设我们有一个指针p,指向一个大小为20的一维数组,它的每个元素都是struct node< /代码>。声明将是:

 struct node (*p) [20];   

现在,如果我们希望 stuct 节点malloc 20 个元素,并希望指针 p应该保存malloc的返回地址,然后我们必须

p = (data-type of p) malloc (size of 20 elements of struct node); 

找到p的数据类型,为了进行转换,我们只需使变量名称消失或替换p > 有一个空白。所以现在

p = (struct node (*)[20] ) malloc(size of 20 elements of struct node);

我们不能在这里出错,因为如果我们错了,编译器会抱怨。终于有尺寸了!我们只是按照我们所描述的标准方式进行,那就是

p =  (struct node (*)[20] ) malloc(sizeof (*p));

我们就完成了!

This is the correct way:

Type *t = malloc(sizeof *t); 

Why this is correct?

Because you correctly allocate a size big enough to hold a structure. *t points to a type Type.


This is incorrect way:

Type *t = malloc(sizeof(t)); 

Why this is Incorrect?

sizeof(t) returns size of pointer and not the actual type(i.e: not the size of the structure).
What you need to allocate is size big enough to hold a structure not size equal to pointer to structure.

Note that, Size of an pointer pointing to Any type is same on an system.


Why is the first approach better?
With the first approach, when you change Type, the malloc automatically changes size to be the correct value, you do not have to do that explicitly unlike other ways.

Also, the important part of writing an malloc call is finding the correct size that needs to be passed. The best way to do this is not to look anywhere (because that is when we make the mistake) but only at the left hand side of this malloc statement. Since, it is t in this case therefore the correct size will be sizeof(*t).

How to standardize use of malloc?

With above mentioned correct approach there is one problem say, if we want to malloc say 30 elements. Then our malloc expression becomes:

t = (T *) malloc(30 * sizeof (*T));

This is not the preferred way to write a malloc expression, because one can make a mistake which entering the number 30 in the malloc parameter. What we would like- irrespective of the number of elements required the malloc parameter should always be the standard sizeof(*x) or something similar.

So here is an approach with an example:

Suppose we have a pointer p, pointing to a single dimensional array of size 20, whose each element is struct node. The declaration will be:

 struct node (*p) [20];   

Now if we wish to malloc 20 elements of stuct node, and wish that pointer p should hold the return address of malloc then we have

p = (data-type of p) malloc (size of 20 elements of struct node); 

To find the data type of p, for casting we just make the variable name disappear or replace p with a blank. So we now have

p = (struct node (*)[20] ) malloc(size of 20 elements of struct node);

We can't go very wrong over here because the compiler will complain if we are wrong. Finally the size! We just do the standard way we have described, that is

p =  (struct node (*)[20] ) malloc(sizeof (*p));

And we are done!

忘羡 2024-12-10 22:27:30
Type *t = malloc(sizeof *t); 

这是分配新实例所需内存量的正确方法。

Type *t = malloc(sizeof (t)); 

这只会为指针分配足够的存储空间,而不是实例。

Type *t = malloc(sizeof *t); 

This is the correct way to allocate the amount of memory needed for a new instance.

Type *t = malloc(sizeof (t)); 

This will only allocate enough storage for a pointer, not an instance.

永不分离 2024-12-10 22:27:30

sizeof(*t),因为 t 的类型为 Type*,因此 *t 指向某种类型类型

但我建议改用它,因为它更具可读性并且不易出错:

Type *t = malloc(sizeof(Type));

sizeof(*t), because t is of type Type* so that *t points to something of type Type.

But I would suggest to use this instead, because it's more readable and less error prone:

Type *t = malloc(sizeof(Type));
草莓酥 2024-12-10 22:27:30

这一个:

Type *t = malloc(sizeof(*t));

您为结构分配内存,而不是为指针分配内存。

this one:

Type *t = malloc(sizeof(*t));

you allocate memory for the struct, not for a pointer.

诗笺 2024-12-10 22:27:30

第一个是正确的。第二个不会分配足够的内存,因为 t 具有指针的大小。
更好的是

Type *t = malloc(sizeof(Type));

The first is correct. Second will not allocate enough memory, because t has the size of a pointer.
Better yet is

Type *t = malloc(sizeof(Type));
心的位置 2024-12-10 22:27:30

最好是: Type * t = malloc(sizeof(Type));

可以说,sizeof *t 也可以工作,并允许您更改 *t 的实际类型 不需要您修改两个单独的位置,但在初始分配中使用类型而不是表达式感觉更具可读性和表现力......不过,这是主观的。如果您想保留更改类型的选项,我个人更喜欢将更改考虑到 typedef 而不是变量声明/初始化中。

Preferably: Type * t = malloc(sizeof(Type));

Arguably, sizeof *t works as well and allows you to change the actual type of *t without requiring you to modify two separate locations, but using the type rather than an expression in the initial allocation feels more readable and expressive... that's subjective, though. If you you want to keep your options open to change the type, I'd personally prefer factoring that change into the typedef rather than the variable declaration/initialization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文