我遇到了一个问题,我需要有人来解释发生了什么。
我正在解析一个像a=1&b=2&c=3
这样的字符串,我想把它解析成["a=1","b=2","c=3"]
,然后拆分每个x=y
。
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void f2(char *src)
{
char *dest = (char *) calloc(strlen(src)+1,sizeof(char));
strcpy(dest,src); // I copy src to dest to guard src from being messed up with strtok
// when I comment out the below line, src address doesn't change
// but why is it changing the src address? I have copied the src to dest!
char *token = strtok(dest, "=");
printf("dest addr: %p token addr: %p \n",dest,token);
}
void f1(char *src)
{
char *token = strtok(src, "&");
while (token)
{
printf("src addr: %p ", token);
f2(token);
token = strtok(NULL, "&");
}
}
我运行代码如下:
TEST(CopyPointer, CopyStrTok)
{
char str[]="a=1&b=2&c=3";
f1(str);
}
结果如下:
src addr: 0x7ffd4a00ec0c dest addr: 0x558a755d3350 token addr: 0x558a755d3350 // it's fine
src addr: 0x558a755d3352 dest addr: 0x558a755d3370 token addr: 0x558a755d3370
// ^ ^
// now src addr is changed and it's pointing to the second character of dest
我不能解释为什么src
是由f2
操作的,而我已经将src
复制到另一个名为dest
的变量?
更正:
正如其中一个答案中提到的,src
地址没有改变,只是令牌地址改变了!
3条答案
按热度按时间jyztefdp1#
strtok
函数使用静态内部数据来跟踪它的位置。因此,当你在
f1
中调用strtok
时,它与该函数中的src
相关联(这与测试函数中的str
相同),但当你在f2
中再次调用它并将dest
作为第一个参数时,它现在与f2
中的dest
关联。然后,当你在f1
中再次调用strtok
,并将NULL
作为第一个参数时,它使用了一个内部指针,指向一个不再在作用域中的dest
成员。这会触发undefined behavior。如果你想使用多个级别的
strtok
,你应该使用strtok_r
,它允许用户传入一个附加参数来存储它的状态。输出量:
clj7thdc2#
为什么要搞得这么复杂?目标是提取字符串的 * 对 *:
输出量:
sqserrrh3#
src
没有改变,你看到的变化,因为你不打印src
只有token
(但在你的格式字符串是src而不是令牌)校正版本