未定义的行为:strtok
undefined behaviour: strtok
如果 sprt 不存在于 str 中,则下面的函数 tokenize 旨在将 *size 设置为 0 - 因此如果 sprt 指向“|”和 str 到 "D AO D",chunk[1] 应该指向一个 NULL 指针并且 n 被设置为 0:
void
tokenize(char *str,
const char *sprt /*separator*/,
char **buffer,
int *size /*tokens length*/)
{
char *chunk[2] = {NULL, NULL};
//store str value into chunk[0]
chunk[0] = calloc(strlen(str)+1, sizeof(char));
strcpy(chunk[0], str);
if (buffer!=NULL)
{
int sz = 0;
chunk[1] = strtok(str, sprt);
while (chunk[1]!=NULL)
{
buffer[sz] = calloc(strlen(chunk[1])+1, sizeof(char));
strcpy(buffer[sz], chunk[1]);
chunk[1] = strtok(NULL, sprt);
sz++;
}
}
else
{
*size=0;
//if chunk is not NULL, the iteration begins => size > 0
chunk[1] = strtok(str, sprt);
while (chunk[1]!=NULL)
{
(*size)++;
chunk[1] = strtok(NULL, sprt);
}
printf("size=%i\n", *size);
}
//restore str value from chunk[0]
strcpy(str, chunk[0]);
if (chunk[0]!=NULL) free(chunk[0]);
if (chunk[1]!=NULL) free(chunk[1]);
}
然而,当在以下代码中测试函数时,显示 bug: n really needs to be 0!
,这意味着 strtok
没有像我预期的那样工作:
int main()
{
char *test = calloc(7, sizeof(char));
strcpy(test, "D AO D");
int n;
tokenize(test, "|", NULL, &n);
if (n>0)
printf("bug: n really needs to be 0!\n");
else
printf("no bug\n");
}
我真的不知道是什么导致了这个UB。我做错了什么?
第一个 strtok
调用 returns 指向原始字符串 "D AO D"
的指针,因为此字符串中没有 "|"
分隔符:
chunk[1] = strtok(str, sprt);
然后while
循环条件通过,因为chunk[1]
是一个非空指针:
while (chunk[1]!=NULL)
{
(*size)++;
chunk[1] = strtok(NULL, sprt);
}
和 *size
在第一次迭代中递增。下一个 strtok
调用 returns NULL
遇到终止 '[=20=]'
字节,并且由于未满足条件而终止循环。因此,*size
等于 1
,这是预期的行为。
如果 sprt 不存在于 str 中,则下面的函数 tokenize 旨在将 *size 设置为 0 - 因此如果 sprt 指向“|”和 str 到 "D AO D",chunk[1] 应该指向一个 NULL 指针并且 n 被设置为 0:
void
tokenize(char *str,
const char *sprt /*separator*/,
char **buffer,
int *size /*tokens length*/)
{
char *chunk[2] = {NULL, NULL};
//store str value into chunk[0]
chunk[0] = calloc(strlen(str)+1, sizeof(char));
strcpy(chunk[0], str);
if (buffer!=NULL)
{
int sz = 0;
chunk[1] = strtok(str, sprt);
while (chunk[1]!=NULL)
{
buffer[sz] = calloc(strlen(chunk[1])+1, sizeof(char));
strcpy(buffer[sz], chunk[1]);
chunk[1] = strtok(NULL, sprt);
sz++;
}
}
else
{
*size=0;
//if chunk is not NULL, the iteration begins => size > 0
chunk[1] = strtok(str, sprt);
while (chunk[1]!=NULL)
{
(*size)++;
chunk[1] = strtok(NULL, sprt);
}
printf("size=%i\n", *size);
}
//restore str value from chunk[0]
strcpy(str, chunk[0]);
if (chunk[0]!=NULL) free(chunk[0]);
if (chunk[1]!=NULL) free(chunk[1]);
}
然而,当在以下代码中测试函数时,显示 bug: n really needs to be 0!
,这意味着 strtok
没有像我预期的那样工作:
int main()
{
char *test = calloc(7, sizeof(char));
strcpy(test, "D AO D");
int n;
tokenize(test, "|", NULL, &n);
if (n>0)
printf("bug: n really needs to be 0!\n");
else
printf("no bug\n");
}
我真的不知道是什么导致了这个UB。我做错了什么?
第一个 strtok
调用 returns 指向原始字符串 "D AO D"
的指针,因为此字符串中没有 "|"
分隔符:
chunk[1] = strtok(str, sprt);
然后while
循环条件通过,因为chunk[1]
是一个非空指针:
while (chunk[1]!=NULL)
{
(*size)++;
chunk[1] = strtok(NULL, sprt);
}
和 *size
在第一次迭代中递增。下一个 strtok
调用 returns NULL
遇到终止 '[=20=]'
字节,并且由于未满足条件而终止循环。因此,*size
等于 1
,这是预期的行为。