malloc
通常用于为某些原始数据类型(int
,float
,char
)的 n 元素分配内存。这看起来像这样:
#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
所需)。
答案 0 :(得分:1)
是的,您可以使用malloc来分配结构数组。
7.22.3内存管理功能
- 通过连续调用分配的存储的顺序和连续性 未指定aligned_alloc,calloc,malloc和realloc函数。的的 指针返回如果分配成功被适当地对齐,以便可以将其分配给 指向具有基本对齐要求的任何类型对象的指针然后使用 在分配的空间中访问这样的对象或这些对象的数组(直到空间 明确解除分配)。 ...
醇>
但你不需要做那些丑陋的演员:
struct a *mem = malloc(N * sizeof(struct a));
for (int i = 0; i < 10; ++i)) {
mem[i] = /* something valid */;
struct a var = mem[i];
}
答案 1 :(得分:1)
以下是否定义明确?
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 */;
}
`