gpt4 book ai didi

c - void* 类型转换打破了严格的别名?

转载 作者:行者123 更新时间:2023-12-01 12:49:46 24 4
gpt4 key购买 nike

我写了一个这样的动态数组:

#include <stdlib.h>

typedef struct {
size_t capacity;
size_t len;
} __dynarray_header;

void* dynarray_new() {
__dynarray_header* header = malloc(sizeof(__dynarray_header));
header->capacity = 0;
header->len = 0;
return header + 1;
}

可以使用[] 操作访问动态数组。调整大小时,我可以使用 __dynarray_header*)array - 1 来检索容量和长度信息。

这个想法在小测试中有效。但是,GCC 警告不要打破严格别名。

我还发现一些较大的项目在没有 -fno-strict-aliasing 编译器选项(使用 -O3 优化)的情况下会出现段错误。

我知道什么是严格别名,以及为什么我的代码会破坏严格别名。

我的问题是:有没有比我上面展示的更好的方法来实现支持 [] 操作和动态调整大小的动态数组?

额外的:

使用这个动态数组的演示程序:

int* arr = dynarray_new();
arr = dynarray_resize(sizeof(int) * 2);
arr[0] = 1;
arr[1] = 2;
arr = dynarray_resize(sizeof(int) * 4);
arr[2] = 3;
arr[3] = 4;
dynarray_free(arr);

最佳答案

正如已经提到的,C 标准为这种事情预见的技术是灵活的数组:

typedef struct {
size_t capacity;
size_t len;
unsigned char data[];
} dynarray_header;

如果您分配(或重新分配)这样一个具有足够空间的 struct,您可以像访问任何 unsigned char 数组一样访问 data 元素. char 类型可以作为任何其他数据类型的别名,因此您不会有任何问题。

如果您的编译器不支持灵活数组,只需将 [1] 放在那里作为 data

顺便说一句,以下划线开头的名称在文件范围内保留,您不应该使用这些。

关于c - void* 类型转换打破了严格的别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17417410/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com