C - 在 malloc() 中计算总和并乘以 sizeof

C - computing sum and multiply it by sizeof in malloc()

我对 malloc() 中的内存分配有疑问。我有一个整数值 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,也能改变点什么?

首先,please see this discussion on why not to cast the return value of malloc() and family in C..

也就是说,malloc() 接受要分配的内存字节数的参数。

引用 C11,章节 §7.22.3.4,malloc() 函数

void *malloc(size_t size);

The malloc function allocates space for an object whose size is specified by size [...]

因此,只要 xy 的计算结果相同,

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_tint的范围。 size_t 通常是 int 正值范围的两倍甚至更多。很少会更少。推荐:

int *p = malloc(sizeof *p * k);

备注:

  1. 不需要转换 malloc() 的结果。
  2. 使用 sizeof *p 而不是 sizeof(int) 不太可能出现错误代码,更容易审查和维护。
  3. 首先使用 sizeof *p 可以确保至少使用 size_t 数学来进行以下大部分数学运算。