我今天发现了一些非常奇怪的东西。
在上面的代码中,我看到utrlen(&eot)
(utrlen == strlen)等于2,utrlen(&etx) == 1
。
最好的部分:当我用etx交换声明顺序时,utrlen(&eot) == 1
和utrlen(&etx) == 2
......
char **get_ukey_string()
{
static char eot = 0x4;
static char etx = 0x3;
static char *ukey_string[NB_UKEY] = {
"\b", "\r", "[B", "\0", "\n", "[D", "[C", "[A", &etx, &eot
};
return (ukey_string);
}
t_hashtable *new_ukey_htable(int fd)
{
char **ukey_string;
t_hashtable *htable;
t_hashnode *hnode;
char *key;
unsigned int i;
size_t size;
if ((htable = new_hashtable(NB_UKEY)) == NULL)
return (NULL);
ukey_string = get_ukey_string();
i = 2;
while (i < NB_UKEY + 2)
{
key = ukey_string[i - 2];
size = utrlen(key);
if (((hnode = new_hashnode(sutrdup(key, size), size, i)) == NULL)
|| htable->add_node(htable, hnode))
{
delete_hashtable(htable);
return (NULL);
}
++i;
}
return (htable);
}
有谁知道为什么?
答案 0 :(得分:3)
eot和etx是char,而不是char *,所以你不能对它们应用strlen,因为没有null终止符。
答案 1 :(得分:2)
strlen
函数(为什么要调用它utrlen
?)接受const char*
类型的参数。该参数必须指向字符串的初始字符,定义为“由第一个空字符终止并包含第一个空字符的连续字符序列”。
使用声明的strlen
对象的地址调用char
是合法的;地址类型char*
(指向char
的指针)匹配要传递给strlen
的所需类型。但它不是字符串的初始字符,因此行为未定义。
实际上,strlen
将从您为其提供地址的char
对象开始,并进行迭代直至看到空字符'\0'
。
如果char
对象恰好具有值'\0'
,它会立即找到它并返回0
- 这不是特别有用。
如果它有其他值,strlen
将尝试扫描内存中不属于对象的字节。结果是未定义的行为。
不要那样做。