【发布时间】:2015-10-08 19:53:42
【问题描述】:
我用 C 语言编写了以下函数来尝试对字符串进行标记。 该函数接受一个要标记的字符串(char * string),以及用于将标记彼此分隔的一串分隔符(char * delimiters)。
char ** tokenize(char * string, char * delimiters)
{
int num_of_tokens = 0;
int itr = 0;
char ** tokens = NULL;
while (string[itr] != '\0')
{
if (!isDelimiter(string[itr], delimiters))
{
num_of_tokens++; /*if char is not a delimiter, we have found a new token*/
int temp_token_count = num_of_tokens - 1;
tokens = realloc(tokens, num_of_tokens);
tokens[temp_token_count] = malloc(STRING_SIZE * sizeof(char));
while(!isDelimiter(string[itr], delimiters) && string[itr] != '\0')
{
appendChar(tokens[temp_token_count], string[itr]);
itr++;
}
}
itr++;
}
return tokens;
}
在 main 函数中,tokenize 函数的调用如下所示:
int main()
{
char * string = "This would,,,,be";
char * delim = ",.:;*& ";
char ** tokens = tokenize(string, delim);
int x = 0;
while(x<3)
{
printf("%s\n", tokens[x]);
x++;
}
return 0;
}
我希望这个调用产生的输出:
This
would
be
然而,这是输出:
L@?
would
be
考虑到如果我使用“This”作为输入字符串调用标记化函数,这似乎特别奇怪,我收到的结果也完全符合我的预期:
This
我不知道发生了什么,任何帮助将不胜感激,感谢您的宝贵时间!!
编辑:这是 isDelimiter 函数
int isDelimiter(char test_char, char * delimiters)
{
int itr = 0;
while (delimiters[itr] != '\0')
{
if (test_char == delimiters[itr]) return 1;
itr++;
}
return 0;
}
【问题讨论】:
-
显示你的函数 isDelimiter 。
-
tokens = realloc(tokens, num_of_tokens);应该是tokens = realloc(tokens, num_of_tokens*sizeof(char*)); -
关于调用 malloc、calloc 和 realloc: 1) 始终检查 (!=NULL) 返回值以确保操作成功。 2)调用realloc时,不要将返回值直接放入目标指针中。因为,如果重新分配失败,那么原始指针会丢失(用 NULL 覆盖),从而导致内存泄漏。 IE。始终将返回的指针保存在 void * 中,检查 NULL,如果不是 NULL,则保存到目标指针。 3)调用malloc时,参数永远不需要'sizeof(char)',因为它总是1所以没有效果并且代码混乱
-
关于这一行:'tokens = realloc(tokens, num_of_tokens);'要分配的字节数实际上是 'num_of_tokens 乘以 sizeof (char *)' 所以发布的代码没有分配足够的内存
-
变量 'itr' 经常增加一次,因此循环顶部的测试错过了检查字符串结尾或分隔符的字符。强烈建议使用调试器(如 gdb)来单步执行代码,tokenize() 函数可能更好地编写为两状态机。 1) 不在令牌中 2) 在令牌中。那么逻辑会更清晰,更容易发现问题。