在 C 中初始化函数结束后保留​​ strok 标记

Keeping strok tokens after the initialization function ends in C

我有一个 foo() 函数,它使用 strtok() 对字符串进行标记并将标记发送到 fee(char *new_word) ,我需要在此处将其分配给新节点。现在一切都很好,但是当 foo() 和 fee() 结束时,我需要 运行 bar() 来打印链表,据我所知,节点指针中的数据已损坏,我无法使用它。我怎样才能持有代币?

struct node{
 char *word;
 struct node *next;
};

struct node top = NULL;

void foo(){
 char *str = "Some words go here";
 char *token = NULL;
 token = strtok(str, "\n");
 while (token){
    fee(token);
    token = strtok(NULL, "\n");
 }
}

void fee(char * new_word){
 struct node *new_node = malloc(sizeof(struct node));
 new_node->word = new_word;
 new_node->next = head;
 head = new_node;
}

bar(){
  while (top){
     printf("%s\n", top->word);
     top = top->next;
  }
}
int main( int argc, char *argv[] ){
foo();
bar();
return 0;
}

令牌指向原始字符串内存块内的内存位置。当原始字符串被释放时,令牌将指向垃圾。如果您想保留令牌,则必须不释放原始字符串或创建每个令牌的副本(即使用 strcpystrdup - 请参阅下面的评论)。

导致您出现问题的行是 fee() 中的 new_node->word = new_word;。您需要为 new_node->word 分配内存并将 new_word 复制到其中,而不是分配令牌指针。当 foo 执行完毕后,释放字符串内存块。在 bar 执行时,您的令牌指向未分配的内存。

或者,如果你在foo()上面的main中初始化char *str = "Some words go here";,然后传递str(即foo(str)),那也可以因为 str 将保留在范围内。只是不要尝试释放 new_node->word 如果你走这条路,你的程序会崩溃。