使用free()使strtok返回的字符串为空

时间:2013-12-24 11:16:17

标签: c string memory-management strtok

我有以下方法

void set_actions(char *input, char **actions)
{
   int index = 0;
   char *str = (char*)malloc(strlen(input));
   strcpy(str,input);
   char *tok = NULL;
   tok = strtok(str," ");

   while(tok!=NULL)
   {
     actions[index]=tok;
     tok=strtok(NULL," ");
     index++;
   }

   free(str);
}

在main中调用此方法之后:

char *input ="A B C";
char *actions[3];
set_actions(input, actions);

结果是:

actions[0] = is empty
actions[1] = is empty
actions[2] = C

如果我删除“free(str)” 然后

actions[0] = A
actions[1] = B

我做错了什么?

2 个答案:

答案 0 :(得分:1)

strtok修改字符串。因此,它返回的子字符串实际上是您为str分配的缓冲区段,它们不在单独的内存区域中。

在C中,字符串一直运行到下一个空字节(字节值0)。 strtok的工作方式是将字符串分隔符替换为空字节。那么你以前在哪里

+-----+-----+-----+-----+-----+-----+
| 'A' | '␣' | 'B' | '␣' | 'C' |  0  |
+-----+-----+-----+-----+-----+-----+
^
str

(其中'␣'是空格字符),然后在调用strtok后,您有

+-----+-----+-----+-----+-----+-----+
| 'A' |  0  | 'B' |  0  | 'C' |  0  |
+-----+-----+-----+-----+-----+-----+
^           ^           ^
actions[0]  actions[1]  actions[2]
str

只要您使用令牌,就无法释放str。要么制作令牌的副本,要么保留str

答案 1 :(得分:0)

使用

actions[index]=strdup(tok);

而不是

actions[index]=tok;

实际上tok是指向数组str中的地址的指针。当您释放str时,tok将指向已释放的地址。因此,您必须将tok内容的副本保存在另一个内存地址中。 strdup允许分配内存,然后复制此内存中的tok内容

然后当您的action[]数组在代码中变得无用时,不要忘记释放数组中的每个elemet

for (i=0;i<max;i++)
    free(actions[i]);