【问题标题】:Using free() makes string returned by strtok to be empty使用 free() 使 strtok 返回的字符串为空
【发布时间】:2013-12-24 11:16:17
【问题描述】:

我有以下方法

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

我做错了什么?

【问题讨论】:

  • 阅读strtok 的手册并弄清楚它的返回值是什么意思。
  • 除了Kerrek的观点,还需要为空终止符分配空间-char *str = malloc(strlen(input)+1);
  • 发布后不要引用该区域。
  • 请记住,在 free() 它们之后不要访问内存,任何事情都可能发生,你不应该这样做。仅当您确定它们将不再被使用时才执行 free()。

标签: c string memory-management strtok


【解决方案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

【讨论】:

    【解决方案2】:

    使用

    actions[index]=strdup(tok);
    

    而不是

    actions[index]=tok;
    

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

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

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

    【讨论】:

    • 非常感谢,现在我明白为什么了。根据您的解释进行一些更改后,它正在工作!!! :)
    猜你喜欢
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多