ATOM表示指针,指向独占和常量字符串.'C'中的字符串应以'\ 0'结尾.
我将展示两种在'C'中定义'ATOM TABLE'结构的方法:
struct atom1 {
struct atom1 *link;
int len;
char *str;
} *bucket[2048]
Run Code Online (Sandbox Code Playgroud)
和
struct atom2 {
struct atom2 *link;
int len;
char str[1];
} *bucket[2048]
Run Code Online (Sandbox Code Playgroud)
所以,当我想为这两种类型的ATOM分配内存时,我也有两种方法.
// memory + 1 for '\0'
struct atom1 *p = malloc(sizeof(*p) + len + 1);
Run Code Online (Sandbox Code Playgroud)
和
// memory for '\0' is already in the define of struct atom
struct atom2 *p = malloc(sizeof(*p) + len);
Run Code Online (Sandbox Code Playgroud)
所以我们可以看到,当我们想要分配内存时,'atom2'看起来更好.但另一方面,如果我们想要访问字符串的内存,我们将打破'C'的规则,因为'char str [1];' 在'atom2'中.
'atom2'真的很棒吗?
从C99开始,您可以选择使用灵活的数组成员 - 也就是说,与您的相同atom2但未指定数组大小:
struct atom2 {
struct atom2 *link;
int len;
char str[];
} *bucket[2048];
Run Code Online (Sandbox Code Playgroud)
这样您就可以在不违反语言规则的情况下将字符串和结构分配在一起.
在这种情况下,当您分配内存时,请务必考虑nul字符串终止符:
struct atom2 *p = malloc(sizeof(*p) + len + 1);
Run Code Online (Sandbox Code Playgroud)
(注意你也不需要投射结果malloc).
请注意,您的atom1结构包含与a char *在语义上不同的结构char [].指针是占用存储空间的数据成员,可以指向任何位置,而灵活数组成员不占用任何存储空间(除了为其明确分配的存储空间)并始终跟踪对象的其余部分.要使用,atom1您需要分别为struct对象和字符串分配存储空间:
struct atom1 *p = malloc(sizeof(*p));
p->str = malloc(len + 1);
Run Code Online (Sandbox Code Playgroud)
您在问题中建议的分配:
struct atom1 *p = malloc(sizeof(*p) + len + 1);
Run Code Online (Sandbox Code Playgroud)
...至少需要你设置指针,p->str指向正确的位置(类似的东西p->str = ((char *) p) + sizeof(*p))但是我不确定如果你试图将字符串存储在那个位置你就不会调用未定义的行为.