malloc + size_t * 3的地址是否适合任何类型? [英] Is the address of malloc + size_t * 3 aligned for any type?
问题描述
我正在构建一种动态数组(向量),但不是将数据(通常是void *
)嵌入到struct vector
中,而是为struct vector
+字节块保留了空间,一个使用size_t
的数组的示例:
I'm builing a kind of dynamic array (vector), but instead of embedding the data (typically void *
) into a struct vector
, I'm reserving space for a struct vector
+ a chunk of bytes, an example using an array of size_t
's:
#include <stdio.h>
#include <stdlib.h>
struct vector {
size_t capacity;
size_t typesize;
size_t size;
};
#define VECTOR(v) ((struct vector *)((unsigned char *)v - sizeof(struct vector)))
static void *valloc(size_t typesize, size_t size)
{
struct vector *vector;
unsigned char *data;
data = calloc(1, sizeof(*vector) + typesize * size);
if (data == NULL) {
return NULL;
}
vector = (struct vector *)data;
vector->typesize = typesize;
vector->capacity = size;
vector->size = 0;
return data + sizeof(*vector);
}
static void *vadd(void *data)
{
struct vector *vector = VECTOR(data);
unsigned char *new;
size_t capacity;
if (vector->size >= vector->capacity) {
capacity = vector->capacity * 2;
new = realloc(vector, sizeof(*vector) + vector->typesize * capacity);
if (new == NULL) {
return NULL;
}
vector = (struct vector *)new;
vector->capacity = capacity;
vector->size++;
return new + sizeof(*vector);
}
vector->size++;
return data;
}
static size_t vsize(void *data)
{
return VECTOR(data)->size;
}
static void vfree(void *data, void (*func)(void *))
{
struct vector *vector = VECTOR(data);
if (func != NULL) {
for (size_t iter = 0; iter < vector->size; iter++) {
func(*(void **)((unsigned char *)data + iter * vector->typesize));
}
}
free(vector);
}
int main(void)
{
size_t *data;
data = valloc(sizeof(size_t), 1);
if (data == NULL) {
perror("valloc");
exit(EXIT_FAILURE);
}
for (size_t i = 0; i < 10; i++) {
data = vadd(data);
if (data == NULL) {
perror("vadd");
exit(EXIT_FAILURE);
}
data[i] = i;
}
for (size_t i = 0; i < vsize(data); i++) {
printf("%zu\n", data[i]);
}
vfree(data, NULL);
return 0;
}
问题是:malloc
(void *
)的结果的地址+ struct
的大小是否适合任何类型?该代码的行为定义是否正确?
The question is: Is the address of the result of malloc
(void *
) + the size of the struct
well aligned for any type? Is the behaviour of this code well defined?
推荐答案
malloc + size_t * 3的地址是否适合任何类型?
Is the address of malloc + size_t * 3 aligned for any type?
不,不一定.
通过使前缀数据也为基本对准来确定基本对准.
Make certain of fundamental alignment by making the prefix data also of fundamental alignment.
一种方法是使用struct vector
和max_align_t
中的union
. union uvector
的大小将是基本排列的倍数.
One way is to use of union
of struct vector
and max_align_t
. The size of union uvector
will be a multiple of the fundamental alignment.
max_align_t
这是一种对象类型,其对齐方式与实现所支持的对齐方式一样大 在所有情况下;
max_align_t
which is an object type whose alignment is as great as is supported by the implementation in all contexts;
union uvector {
max_align_t a;
struct vector {
size_t capacity;
size_t typesize;
size_t size;
} v;
};
union uvector *uvector;
unsigned char *data;
data = calloc(1, sizeof *uvector ...
...
return data + sizeof *uvector;
答案效率低下-在另一个答案中进行了重新设计.
Answer has some inefficiencies - Reworked in another answer..
这篇关于malloc + size_t * 3的地址是否适合任何类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!