假设我们有一个简单的结构:
typedef struct
{
int d1;
int d2;
float f1;
}Type;
为新实例分配内存时,哪个是正确的:
此:
// 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));
哪个是正确的?
答案 0 :(得分:4)
这是正确的方法:
Type *t = malloc(sizeof *t);
为什么这是正确的?
因为您正确地分配了足够大的尺寸来容纳结构。 *t
指向Type
类型。
这是不正确的方式:
Type *t = malloc(sizeof(t));
为什么这不正确?
sizeof(t)
返回指针的大小而不是实际的类型(即:不是结构的大小)
你需要分配的是足够大的大小来容纳一个大小不等于结构指针的结构。
请注意,指向任何类型的指针的大小在系统上是相同的。
为什么第一种方法更好?
使用第一种方法,当您更改Type
时,malloc
会自动将大小更改为正确的值,您不必像其他方式那样明确地执行此操作。
此外,编写malloc
调用的重要部分是找到需要传递的正确大小。执行此操作的最佳方法是不要查看任何位置(因为这是我们犯错的时候),而只是在malloc
语句的左侧。因为,在这种情况下它是t
因此正确的大小将是sizeof(*t)
。
如何标准化使用malloc
?
如果我们想要malloc
说30 elements
,上面提到的正确方法就有一个问题。然后我们的malloc
表达式变为:
t = (T *) malloc(30 * sizeof (*T));
这不是编写malloc
表达式的首选方法,因为可能会在30
参数中输入数字malloc
时出错。我们想要的是 - 无论malloc
参数所需的元素数量如何,始终应该是标准的sizeof(*x)
或类似的东西。
所以这是一个带有示例的方法:
假设我们有一个指针p
,指向size 20
的单维数组,其每个元素都是struct node
。声明将是:
struct node (*p) [20];
现在,如果我们希望malloc
20 elements
的{{1}} stuct node
,并希望指针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));
我们完成了!
答案 1 :(得分:2)
Type *t = malloc(sizeof *t);
这是分配新实例所需内存量的正确方法。
Type *t = malloc(sizeof (t));
这只会为指针而不是实例分配足够的存储空间。
答案 2 :(得分:1)
sizeof(*t)
,因为t
的类型为Type*
,因此*t
指向Type
类型的内容。
但我建议使用它,因为它更具可读性且不易出错:
Type *t = malloc(sizeof(Type));
答案 3 :(得分:1)
这一个:
Type *t = malloc(sizeof(*t));
为结构分配内存,而不是指针。
答案 4 :(得分:0)
最好:Type * t = malloc(sizeof(Type));
可以说,sizeof *t
同样适用,允许您更改*t
的实际类型,而无需修改两个单独的位置,但在初始分配中使用类型而不是表达式会感觉更多但是可读和富有表现力......这是主观的。如果你想让你的选项保持开放以改变类型,我个人更喜欢将更改分解为typedef而不是变量声明/初始化。
答案 5 :(得分:0)
第一个是正确的。第二个不会分配足够的内存,因为t
具有指针的大小。
更好的是
Type *t = malloc(sizeof(Type));