我正在为一个赋值编写一个程序,我遇到了部分问题,我应该分叉,使用exec()运行mkdir来创建一个目录,如果它不存在的话。我有2个具有此功能的独立功能。它适用于第一个函数,但第二个函数总是得到错误Bad Address。我不知道为什么会发生这种情况,就像在我看来,就我对局部变量的理解以及它应该起作用的内容而言。为了澄清,'new'是命令行中给出的期望路径。
如果有人对可能会出现什么样的问题有任何想法。 (以下代码)
if(chdir(new) == -1) //check if desired directory exists, if not create
{
pid_t pid = fork();
char **args;
if((args = malloc(sizeof(char *) * 2)) == NULL)
{
perror("args malloc() failed!");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
args[0] = "mkdir";
args[1] = new;
if(execv("/bin/mkdir", args) == -1)
{
perror("mkdir failed!");
exit(EXIT_FAILURE);
}
}
else if(pid > 0)
{
wait(NULL);
for(int i = 0; i < 2; i++) //free each value of args
{
free(args[i]);
}
free(args); //free args
}
}
答案 0 :(得分:1)
当你fork
时,你得到两个独立的进程(父进程和子进程),每个进程都有自己的内存,并拥有自己内存中所有内容的副本。由于您在调用fork
之后malloc
复制了malloced内存,并且在一个进程中对该内存的后续分配不会影响另一个进程中的内存。
因此,当您为子项中的args[0]
和args[1]
分配值时,父级中的这些元素不受影响;他们还没有初始化。然后在父级中,当你释放args[0]
和args[1]
时,你会得到未定义的行为,因为那些是未初始化的指针。
最简单的解决方法是将malloc调用完全移到子代中(在fork之后) - 然后你根本不需要在父代中担心它。您也不必担心释放孩子的东西(您目前不喜欢),因为所有内存都会在调用exec
时自动释放
更好的是,根本不使用malloc - 只需在子代中使用本地(auto on stack)数组:
if (pid == 0) {
char *args[] = { "mkdir", new, 0 }; // need a null pointer to mark the end of the arg list
execve("/bin/mkdir", args);
perrer("execve failed!") // if execve returns, it failed -- don't actually need to check the error code
答案 1 :(得分:1)
您的代码中存在少量错误
args
是char类型的双指针,你只为args
分配内存,也应分配给args[0]
和args[1]
,那么只有你可以做{{1} }} args[0] = "mkdir";
)而不是doubler指针(char *args[NUM]
)。 这是完整的代码,可以帮助您
char **args