我目前正在C中编写一个新的String结构,如下所示,并练习指针运算。
struct String {
uint32_t check;
uint32_t capacity;
uint32_t length;
char data[1];
} String;
我对这部分代码感到有点困惑
define STRING(s) ((String*)(s - 3*sizeof(uint32_t)))
void utstrfree(char* self) {
// if(*(self - sizeof(uint32_t) * 3) == SIGNATURE) WHY DOES THIS NOT >WORK?
assert((STRING(self)->check) == SIGNATURE); //check if it's a >utstring
free(self-sizeof(uint32_t) * 3); //properly free the malloc and alternative could have been free(STRING(self))
}
我理解我的STRING宏如何工作并且它正常工作但我不太清楚为什么我的if语句不起作用。任何人都可以向我解释这个吗?
答案 0 :(得分:2)
正如@AslakBerby已经观察到的那样,断言中的表达式(我假设 )起作用,并不等同于已注释掉的if
语句中的条件表达式。特别是,由于self
是char *
,因此表达式*(self - sizeof(uint32_t) * 3)
的类型为char
,而表达式STRING(self)->check
的类型为uint32_t
。假设对后者进行评估已经定义了行为,前者仅在系统特定的存储顺序中产生后者的第一个字节。
总的来说,尽管这个一般方案起作用,但它很脆弱且不安全:
struct String
的表示不需要实现; 建议:
offsetof()
计算结构中的相对位置。它既安全又清晰。char
数组字符串直接互操作 - 将这些对象处理为实际的对象。毕竟,这种练习的重点通常不是数据结构本身,而是与之相关的改进功能,例如strlen()
的O(1)版本。没有必要尽量使用标准库的功能来使用这些对象。答案 1 :(得分:1)
好吧,你的if不等于宏。如果你应该输入它,它应该是这样的:
if(((String*)(self - 3*sizeof(uint32_t)))->check) == SIGNATURE) ...
您需要对您创建的指针进行类型转换,然后使用您要查找的属性。