如何解决如何处理 C
我正在用 C 实现一个任意类型的动态数组。实现的工作原理是在数组数据之前分配一个标头:
typedef struct
{
unsigned char* begin; // Pointer to data
unsigned char* end; // Pointer to last element
size_t typeSize; // Size of type
size_t capacity; // Capacity of array (not number of elements in array)
} dynamicArr;
#define dynamicArr_ConstructBase(dest,src,newCapacity) \
dest = src; \
dest->capacity = newCapacity; \
dest->begin = (unsigned char*)dest + sizeof *dest
#define dynamicArr_Construct(dest,newCapacity,currSize,typeSize) \
dynamicArr_ConstructBase(dest,newCapacity); \
dest->end = dest->begin + typeSize * (currSize)
#define dynamicArr_Header(arr) ((dynamicArr*)((unsigned char*)(arr) - sizeof(dynamicArr)))
static inline size_t dynamicArr_Size(dynamicArr* arr)
{
return (arr->end - arr->begin) / arr->typeSize;
}
#define dynamicArr_Create(typename,arr) typename* arr = (typename*)dynamicArr_Create_(sizeof(typename))
static inline unsigned char* dynamicArr_Create_(size_t typeSize)
{
dynamicArr* dynArr;
void* tmp = malloc(sizeof * dynArr + typeSize * 10);
if (!tmp) return NULL;
dynArr = tmp;
dynArr->begin = (unsigned char*)dynArr + sizeof * dynArr;
dynArr->end = dynArr->begin;
dynArr->capacity = 10;
dynArr->typeSize = typeSize;
return dynArr->begin;
}
#define dynamicArr_Free(arr) free(dynamicArr_Header(arr))
#define dynamicArr_Push(arr,item) \
do \
{ \
if (arr) \
{ \
dynamicArr* header = dynamicArr_Header(arr); \
if (header->typeSize && header->typeSize == sizeof item) \
{ \
size_t arrSize = dynamicArr_Size(header); \
if (arrSize == header->capacity) \
{ \
size_t newCapacity = (size_t)(header->capacity * 1.5f); \
if (newCapacity == header->capacity) ++newCapacity; \
void* tmp = realloc(header,sizeof(dynamicArr) + header->typeSize * newCapacity); \
if (tmp) \
{ \
dynamicArr_Construct(header,tmp,arrSize,header->typeSize); \
*((void**)&(arr)) = header->begin; \
arr[arrSize] = item; \
header->end += header->typeSize; \
} \
else \
{ \
free(header); \
arr = NULL; \
} \
} \
else \
{ \
arr[arrSize] = item; \
header->end += header->typeSize; \
} \
} \
} \
} while(0)
示例使用:
void Func()
{
dynamicArr_Create(int,intArr);
dynamicArr_Push(intArr,10);
printf("%i\n",intArr[0]);
dynamicArr_Free(intArr);
}
这个问题是我认为这是未定义的行为,因为如果编译器选择使用对齐的指令作为标头之后的数组项,则可能未对齐。
有没有办法保证item的对齐?
我已经研究过使用灵活的数组成员,但是我不确定如何实现它以使其适用于任意类型。
例如,我可以像这样声明标题:
#define dynamicArr_Header(type) \
struct \
{ \
size_t typeSize; \
size_t capacity; \
type data[]; \
}
但是,如果我要在代码中使用它,我的编译器会警告我 '=': incompatible types - from '*' to '*'
。
导致警告的示例:
dynamicArr_Header(int)* A = malloc(sizeof(dynamicArr_Header(int)));
dynamicArr_Header(int)* B = A; //Causes warning
这样做危险吗?这是因为匿名结构体真的不是同一种类型,还是会导致更多的问题(比如我是否可以保证编译器以相同的方式填充和打包这些结构体)?
灵活数组成员方法的另一个“问题”是,我必须传递标头指针,这与以前的方法不同,我可以只提供指向数据的指针。我知道我可以使用灵活的数组版本:
int* pntrToIntArr = &header->data[0];
但是我希望标题被抽象掉,但是如果我提供了指向数据数组的指针,我将如何检索标题?我可以只做(dynamicArr_Header(int)*)((unsigned char*)pntrToIntArr - sizeof(dynamicArr_Header(int)))
吗?
如果不破坏严格的别名/对齐规则,我在 C 中做的事情是不可能的吗? 我知道我可能违反了很多指针语义的严格别名规则。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。