我有一个关于malloc()
中内存分配的问题。我有一个int值k
。这些分配方式的区别是什么
...=(int*)malloc(k*sizeof(int));
和
...=(int*)malloc(((2*k-1)-k+1)*sizeof(int));
知道(2*k-1)-k+1) == k
?
两者的结果是相同的,或者在第二种情况下,即使((2*k-1)-k+1) == k
也能改变一些东西?
首先,请参阅关于为什么不在C
中强制转换malloc()
和family的返回值的讨论。
也就是说,malloc()
接受要分配的内存字节数的参数。
引用C11
, chapter§7.22.3.4, malloc()
函数
void *malloc(size_t size);
malloc
函数为大小由size
[…]指定的对象分配空间
因此,只要x
和y
的计算结果相同,
malloc(x * sizeof(sometype))
和
malloc(y * sizeof(sometype))
如果调用成功,将为您提供具有相同内存量的指针。
最后,不使用sizeof
操作符的硬编码值,而使用变量本身总是更好的方法。使代码更健壮,如
int *p = NULL;
.
.
.
p = malloc (x * sizeof(*p)); // type of `p` can change,
// this statement need not be changed
虽然在数学上等同于k
,但乘积(2*k-1)-k+1
可能溢出导致未定义行为。int
范围的一半与使用k
的差异。
... = malloc(((2*k-1)-k+1)*sizeof(int))
k*sizeof(int)
产品本身使溢出,但产品定义良好,即使不理想。
溢出的可能性取决于size_t
和int
的范围。size_t
的阳性范围通常是int
的两倍,甚至更多。很少少。推荐:
int *p = malloc(sizeof *p * k);
指出:
- 不需要转换
malloc()
的结果。 - 使用
sizeof *p
而不是sizeof(int)
更不容易出错,更容易检查和维护。 - 首先使用
sizeof *p
可以确保至少使用size_t
的数学来进行以下计算。