C - malloc 的返回值可以像数组一样使用(对齐)吗?

标签 c pointers alignment malloc

malloc 通常用于为某些原始数据类型(intfloat字符)。这可能看起来像这样:

#define N 10

double *mem = malloc(N * sizeof(double));

for (int i = 0; i < N; ++i) {
  mem[i] = 10.0;       // Write
  double d = mem[i];   // Read
}

如果我将 mem 声明为 char * 并稍后使用转换,这甚至会起作用:

char *mem = malloc(N * sizeof(double));

for (int i = 0; i < N; ++i) {
  *(double*)(mem + i * sizeof(double)) = 10.0;
  double d = *(double *)(mem + i * sizeof(double));
}

目前我想知道这是否定义良好并且适用于每种数据类型(甚至任何复杂类型,如 struct)。让我们假设 struct a 可以是任何东西。以下是否明确定义?

char *mem = malloc(N * sizeof(struct a));

for (int i = 0; i < 10; ++i)) {
  *(struct a *)(mem + i * sizeof(struct a)) = /* something valid */;
  struct a x = *(struct a *)(mem + i * sizeof(struct a));
}

由于 malloc 的返回值适合任何类型的变量,因此 i = 0 的情况肯定定义明确且有效,但是 I 怎么样= 1, 2, ...?对齐会搞砸吗?就像这个例子:

char char_arr[4] = /* some value */;
int *d = &char_arr[0];

第二行不能保证有效,因为 char_arr 可能不会在 4 字节边界上对齐(int 需要)。

最佳答案

Is the following well defined?

char *mem = malloc(N * sizeof(struct a));

for (int i = 0; i < N /* 10 */; ++i)) {
  *(struct a *)(mem + i * sizeof(struct a)) = /* something valid */;
  // struct a = *(struct a *)(mem + i * sizeof(struct a));
  struct a x = *(struct a *)(mem + i * sizeof(struct a));
}

几乎总是。

在对齐方面,*alloc()如 OP 所述,返回对所有基本对齐有效的内存指针。 (struct a *)(mem + i * sizeof(struct a))还将为所有 0 <= i <= N 提供一个对齐良好的指针.

OP 不太可能担心,但在稀有机器上 i * sizeof(struct a)会溢出size_t数学(足够大的 isizeof(struct a) ,而 mem[i] 不会。这在使用 flat memory 地址的常见实现中看不到。


还有强大的代码检查内存分配失败。


候选简化代码。注意类型 ptr指向不相关,假设未定义 void *ptr . @usr .

ptr = malloc(sizeof *ptr * N);
if (ptr == NULL) Handle_OOM();

for (size_t i = 0; i < N; ++i)) {
  ptr[i] = /* something valid */;
}

`

关于C - malloc 的返回值可以像数组一样使用(对齐)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43256625/

相关文章:

c - 创建用于矩阵加法的库函数时传递给函数的最小参数数量是多少

c++ - Word 解读程序 - C++

c++ - 如何使用指向指针的指针存储 Polyomino 的对称性?

c - 带指针的递归 -C

c - 打印字符串指针导致 C 中的输出损坏

javascript - 如何添加允许在 Umbraco 中添加新行的验证

c - NULL 指针与零段错误的比较

html - 用 css 和 div 模拟 rowspan?

css - 更改div或div的内容?

html - 水平居中一个元素并将另一个元素放在它的右边