我已经阅读了Cello fat pointer library,并想知道在C中实际上是否允许在某些数据前加上标题,例如像这样的东西:
struct header
{
size_t length;
};
char* create_string(const char* cstr)
{
void* ret = malloc(sizeof(struct header)+strlen(cstr)+1);
((struct header*)ret)->length = strlen(cstr);
strcpy((char*)ret + sizeof(struct header), cstr);
return (char*)ret + sizeof(struct header);
}
size_t get_length(const char* sized_string)
{
struct header* tmp = sized_string - sizeof(struct header);
return tmp->length;
}
这个例子是一个字符串,但它可能是存储的任何其他内容,甚至可能是一个不是数组的东西,在这种情况下,标题可能有不同类型的元数据。
我知道sds使用灵活的数组成员,但这需要c99并且不像这种方法那么灵活(除非你只使用了一个通用的char数组并根据需要重新设置它)。
具体而言in this question人说以下内容实际上并不可移植:
struct header {
size_t len;
unsigned char data[1];
};
因为访问第一个元素之外的数据是UB。另一件事是((struct header*)ret)->length = strlen(cstr);
和struct header* tmp = sized_string - sizeof(struct header);
行看起来不对(因为指针强制转换),我没有看到更好的方法来编写它们。
答案 0 :(得分:6)
您的示例仅放置和读取固定偏移量。所以至少指针算术是完全合法的。至少只要类型只是malloc
。
但问题是对齐。这还没有违反语言标准,但是实际数据的对齐比例如x86上的编译器默认提供。
因此,如果编译器默认情况下对齐为8个字节(x86上的gcc和msvc)或16个字节(x64上),则示例代码仅提供对齐的一半。
如果编译器假设对齐的内存(否则可以通过匹配Function GetName(Source As String)
Dim arr() As String 'declares a dynamic array
arr = VBA.Split(Source, " ") 'an array of words split by space from the Source string is built
'Ubound function gets the last position of items in the array
Name = ""
For i = LBound(arr) To UBound(arr)
Name = Name + " " + arr(i)
Next i
End Function
实现来确保,以及堆栈布局和结构中的填充),这可能是非法的。根据架构,它甚至可能导致错误,因为指令可能需要最小的对齐。