当你在C中的一个char指针上调用strtok时会发生什么让我感到困惑。我知道它会修改字符串的内容,所以如果我在一个名为'line'的变量上调用strtok,它的内容就会改变。假设我遵循以下方法:
void function myFunc(char* line) {
// get a pointer to the original memory block
char* garbageLine = line;
// Do some work
// Call strtok on 'line' multiple times until it returns NULL
// Do more work
free(garbageLine);
}
进一步假设'line'在传递给myFunc之前被malloced。我应该在使用strtok之后释放原始字符串还是为我们完成工作?另外,如果'line'没有被malloced并且我尝试使用上面的函数会发生什么?取而代之的是更安全吗? (假设程序员不知道该行未被malloced,则不会免费拨打电话)
调用
char* garbageLine = line;
myFunc(line);
free(garbageLine);
功能定义
void function myFunc(char* line) {
// Do some work
// Call strtok on 'line' multiple times until it returns NULL
// Do more work
}
答案 0 :(得分:9)
strtok()不会释放任何内容,因为它不知道字符串的存储位置。它可能在堆栈或堆上,它不知道或关心! :)
执行以下操作会更安全吗?
你的第二个例子要好得多,因为它简化了myFunc(),并且在更多情况下使它很有用,因为函数不需要知道字符串的分配位置。通过从myFunc()中删除对free()的调用,您可以使用该函数来解析堆栈或堆中的字符串。调用者分配内存,调用者释放内存!
进一步阅读: strtok()
答案 1 :(得分:4)
在你的问题的评论中,你说你“多次在'线'上调用strtok直到它返回NULL”。这听起来好像你可能错误地使用了strtok。第一次调用它时,你应该用'line'作为参数调用它;在后续调用中,您应该将其传递为NULL。以下面的例子为例:
void function myFunc(char* line) {
char *segment; // This will point at each delimited substring in turn.
segment = strtok(line, " ");
// Do something with segment.
segment = strtok(NULL, " ");
// Do something with the new segment.
free(line);
}
正如DrTwox所说,你的第二个例子更好 - 'line'应该被malloced(或不是)的相同上下文释放,所以对free()的调用不属于这个函数。你最好还是循环它 - 比如:
void function myFunc(char* line) {
char *segment;
segment = strtok(line, " ");
while (segment != NULL) {
// Do something with segment.
segment = strtok(NULL, " ");
}
}
调用是这样的:
char *line = malloc(20*sizeof(char));
// Check that malloc succeeded here.
// Put some data into 'line'.
myFunc(line);
free(line);
// No 'garbageLine' required.
strtok的工作方式有点复杂,但你有重要的部分 - 它没有分配或释放任何记忆。相反,它通过修改传递给它的字符串来工作。
答案 2 :(得分:1)
答案 3 :(得分:1)
值得解释的是strtok
通过以下方式来完成其工作:
返回指向原始字符串的指针;和
将找到的每个分隔符替换为NULL。
因此,所有内容都就位,并且不需要分配任何内存。
答案 4 :(得分:0)
这与strtok()
有什么关系?如果你分配内存,你需要释放它。您的应用程序决定分配和释放内存取决于您。但是如果你将内存传递给strtok()
,那么只要内存被分配或释放,就没有任何区别。