malloc
通常用于为某些原始数据类型(int
、float
、 字符
)。这可能看起来像这样:
#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
数学(足够大的 i
和 sizeof(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/