strtok() 覆盖它的源字符串
strtok() overwrites its source string
我正在写一个玩具bashshell。我现在的目标是在环境中循环寻找可以找到特定命令的路径。现在我正在用“:”分隔路径(例如“/home/user/bin:home/user/.local/bin:/usr/local/sbin”等),对于给我的每条路径,将该路径复制到新字符串 finalPath
,然后将“/cmd”连接到末尾。
我的问题是,当我尝试将路径的内容复制到 finalPath
时,我对 finalPath
所做的任何更改都会反映到路径中。由于代码是正确的,path
只会被设置为 "home/user/bin" 一次,循环并再次设置为相同的东西,然后分词器命中 "NULL" 并终止 while 循环。
这表明 path
和 finalPath
正在共享一个内存地址,但是由于 strcpy 理论上在内存中创建了一个新副本,所以我的字符串和指针一定有问题。
知道是什么导致了这种意外行为吗?
编辑:当我注释掉 strcpy
时,这段代码按预期执行
我的代码的精简版如下:
int findpath(char* cmd, command_t* p_cmd) {
char* path_var;
path_var = getenv( "PATH" );
char* path;
char tempEnv[sizeof(path_var)];
strcpy(tempEnv, path_var);
path = strtok(tempEnv, ":");
while(path != NULL) {
char fullPath[1000];
strcpy(finalPath, path);
printf("path: %s\n", path);
printf("finalPath: %s\n", finalPath);
path = strtok(NULL, ":");
}
BLUEPIXY 是正确的:tempEnv
对您的字符串来说不够大。尝试:
char *tempEnv;
tempEnv = malloc(strlen(path_var)+1);
strcpy(tempEnv, path_var);
最后
free(tempEnv);
前提是这里漏洞百出。您应该使用更安全的字符串函数,例如,如 here. For example, use strnlen
所述,以强制对 path_var
的长度设置一些合理的限制。确保 path_var
在该限制内以 NULL 结尾。使用 strncpy
而不是 strcpy
。如有必要,在 strncpy
之后添加 NULL。还有许多其他规则,我没有在此处包括这些规则,因为您的目标似乎是学习而不是生产代码。快乐黑客!
我正在写一个玩具bashshell。我现在的目标是在环境中循环寻找可以找到特定命令的路径。现在我正在用“:”分隔路径(例如“/home/user/bin:home/user/.local/bin:/usr/local/sbin”等),对于给我的每条路径,将该路径复制到新字符串 finalPath
,然后将“/cmd”连接到末尾。
我的问题是,当我尝试将路径的内容复制到 finalPath
时,我对 finalPath
所做的任何更改都会反映到路径中。由于代码是正确的,path
只会被设置为 "home/user/bin" 一次,循环并再次设置为相同的东西,然后分词器命中 "NULL" 并终止 while 循环。
这表明 path
和 finalPath
正在共享一个内存地址,但是由于 strcpy 理论上在内存中创建了一个新副本,所以我的字符串和指针一定有问题。
知道是什么导致了这种意外行为吗?
编辑:当我注释掉 strcpy
时,这段代码按预期执行我的代码的精简版如下:
int findpath(char* cmd, command_t* p_cmd) {
char* path_var;
path_var = getenv( "PATH" );
char* path;
char tempEnv[sizeof(path_var)];
strcpy(tempEnv, path_var);
path = strtok(tempEnv, ":");
while(path != NULL) {
char fullPath[1000];
strcpy(finalPath, path);
printf("path: %s\n", path);
printf("finalPath: %s\n", finalPath);
path = strtok(NULL, ":");
}
BLUEPIXY 是正确的:tempEnv
对您的字符串来说不够大。尝试:
char *tempEnv;
tempEnv = malloc(strlen(path_var)+1);
strcpy(tempEnv, path_var);
最后
free(tempEnv);
前提是这里漏洞百出。您应该使用更安全的字符串函数,例如,如 here. For example, use strnlen
所述,以强制对 path_var
的长度设置一些合理的限制。确保 path_var
在该限制内以 NULL 结尾。使用 strncpy
而不是 strcpy
。如有必要,在 strncpy
之后添加 NULL。还有许多其他规则,我没有在此处包括这些规则,因为您的目标似乎是学习而不是生产代码。快乐黑客!