我有以下方法
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
我做错了什么?
答案 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]);