gpt4 book ai didi

C 结构体指针算术

转载 作者:行者123 更新时间:2023-11-30 18:36:15 26 4
gpt4 key购买 nike

我目前正在用 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 语句不起作用。谁能给我解释一下吗?

最佳答案

正如 @AslakBerby 已经观察到的,我假设您的断言中的表达式确实有效,但它并不等于注释掉的 if 语句中的条件表达式。特别是,由于 selfchar *,因此表达式 *(self - sizeof(uint32_t) * 3) 的类型为 char ,而表达式 STRING(self)->check 的类型为 uint32_t。假设评估后者已经定义了行为,则前者仅产生后者的第一个字节,按照系统特定的存储顺序。

但总的来说,就这个通用方案的工作而言,它是脆弱且不安全的:

  • 它对 struct String 类型的表示进行了假设,但实现不需要满足这些假设;
  • 它经常超出数组范围,从而调用未定义的行为;
  • 它没有提供表示就地子字符串的机制;
  • 它提供了与标准库的字符串函数的足够互操作性,让用户期望获得比实际提供的更高的互操作性。

建议:

  • 依靠 offsetof() 计算结构内的相对位置。它更安全、更清晰。
  • 甚至不要尝试与纯 char 数组字符串进行直接互操作 - 按实际情况处理这些对象。毕竟,此类练习的重点通常不在于数据结构本身,而在于随之而来的改进函数,例如 strlen() 的 O(1) 版本。无需费尽心力来适应这些对象与标准库函数的使用。
  • 考虑使用指向数据的指针,而不是将数据直接嵌入到对象中。这肯定会更好地适应调整大小,并且它也可以支持就地子字符串。
  • 如果您确实将数据直接嵌入到对象中,请使用灵活的数组成员来执行此操作。

关于C 结构体指针算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42260674/

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