1

所以这是我的代码给我带来的问题:

void childProcessHandler(string command){


int argCounter = 0;
for(int i=0; i!=command.size(); i++)
    argCounter+=( command.at(i) == ' ');

char * temp, *token;
char *childArgs[argCounter];

argCounter = 1;

temp = new char [command.size()+1];
strcpy (temp, command.c_str());

token = strtok (temp," ");
childArgs[0] = token;

while (token!=NULL)
{
    token = strtok(NULL," ");
    childArgs[argCounter] = token;
    argCounter++;
}
    
//delete[] temp; //Should remove token as well?

execvp(childArgs[0], childArgs);

cout<<"PROBLEM!"<<endl;
exit(-1);

}

在 main() 方法中,我的代码到达一个点,它 forks() (父进程然后等待子进程退出。)然后子进程(进程 ID == 0 是吗?)调用方法 childProcessHandler 与用户输入(运行命令 + args)作为它的参数。然后我标记用户输入并在其上调用 execvp。

一切都编译并执行。execvp 之后的行永远不会到达,因为 execvp 仅在出现错误时才返回是吗?

该项目是模拟一个unix终端但是当我给它命令“日期”时,没有任何东西像它应该的那样被打印出来......子进程退出并且父进程恢复得很好但是没有任何东西被发送回终端窗口......

我究竟做错了什么?

(我们也被“推荐”使用 strtok 来标记它,但如果有人有更简单的东西,我愿意接受意见。)

谢谢!

编辑

例如,如果我输入“日期”而不是“日期”,则上述代码有效。我认为“标记器”没有在 childArgs[] 数组的末尾放置空字符可能有些可疑。我会解决这个问题,并感谢您的快速回复!

(忍者编辑,暂时还注释掉了delete[] temp)

4

2 回答 2

2

您正在混合 std::string 和 char/char*。很好,但你必须小心,他们有不同的行为。

特别是这一行:

temp = new char [command.size()+1];

正在创建一个实际的数组来保存一个字符串。

token = strtok (temp," ");

这使得令牌(它只是一个指针)指向 temp 中的一个位置。strtok() 修改输入字符串以在字符串中创建一个临时字符串(听起来很疯狂,我知道)。

你需要复制字符串 strtok() 给你一个永久的家。要么使用 std::string 来节省时间和代码,要么使用 char* 方式并自己分配新字符串。例如,而不是:

childArgs[0] = token;

你需要:

   childArgs[0] = new char[strlen(token)+1];
   strcpy(childArgs[0], token);

这同样适用于在命令参数循环期间存储在数组中的标记。

于 2011-09-29T20:25:58.977 回答
1

您的 childargs 指针向量指向在内存块“temp”中分配的字节。当您释放 temp 时,您正在删除 childargs 指针指向的内存,可能会破坏向量中的某些值。

删除对 delete[] 的调用以停止释放 childargs 指针指向的内存。你不会泄漏内存。一旦你调用 exec_ () ,你的整个进程映像就会被替换。调用 exec _() 后唯一幸存下来的(大部分)是您的文件描述符。

作为测试,尝试一些更简单的方法:在孩子中调用 fork() 之后,只需使用“日期”路径调用 exec。在摆弄参数列表向量之前使其工作。

作为另一个测试,删除您对 exec 的调用,并打印出整个指针向量,以确保您的标记化以您认为应该的方式工作。请记住,您的最终条目必须为 NULL,以便您知道向量的末尾在哪里。

于 2011-09-29T20:42:06.027 回答