我正在写一个玩具bash shell。我现在的目标是在环境中循环寻找可以找到特定命令的路径。现在我用“:”分隔PATH(例如“/home/user/bin:home/user/.local/bin:/usr/local/sbin”等),对于给我的每个路径,复制那个新字符串finalPath
的路径,然后将“/ cmd”连接到结尾。
我的问题是,当我尝试将路径内容复制到finalPath
时,我对finalPath
所做的任何更改都会反映到路径中。由于代码现在,path
只会被设置为“home / user / bin”一次,循环并再次设置为相同的东西,然后tokenizer命中“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, ":");
}
答案 0 :(得分:3)
BLUEPIXY是对的:tempEnv
对于你的字符串来说还不够大。尝试:
char *tempEnv;
tempEnv = malloc(strlen(path_var)+1);
strcpy(tempEnv, path_var);
并在最后
free(tempEnv);
附带条件这是充满漏洞的。您应该使用更安全的字符串函数,例如,如here所述。例如,使用strnlen
强制设置path_var
长度的合理限制。确保path_var
在该限制内以NULL结尾。使用strncpy
代替strcpy
。如有必要,在strncpy
之后添加NULL。还有许多其他规则,我不在此处,因为您的目标似乎是学习而不是生产代码。快乐的黑客!