2016-02-06 100 views
0

时,execvp无法正常工作当字符串向量转换为char *向量char *的向量时,当参数以char **形式出现时正在工作,但是转换似乎有问题,我无法找到差异。从矢量<string>转换为矢量<char*>至char **

有没有更好的方法来做到这一点?

vector<string> args; 

    /* code that correctly parses args from user input */ 

    pid_t kidpid = fork(); 
    if (kidpid < 0) 
    { 
     perror("Internal error: cannot fork."); 
     return -1; 
    } 
    else if (kidpid == 0) 
    { 
     // I am the child. 

     vector<char*>argcs; 
     for(int i=1;i<args.size();i++) 
     { 
      char * temp = new char[args.at(i).length()]; 
      for(int k=0;k<args.at(i).length();k++) 
      { 
       temp[k] = args.at(i).at(k); 
      } 
      argcs.push_back(temp); 
     } 

     char** argv = new char*[argcs.size() + 1]; 
     for (int i = 0; i < argcs.size(); i++) 
     { 
      argv[i] = argcs[i]; 
     } 
     argv[args.size()] = NULL; 

     execvp(program, args); 

     return -1; 
    } 
+0

在让我们的问题是什么可能会有帮助。 – user4581301

+0

对不起用户,execvp找不到匹配的构造函数 – redux

回答

3

首先,有一个在复制std::string■如果你要做的下一件事就是调用execvp没有意义的。

如果execvp成功,那么它将永远不会返回,并且整个内存映像将消失为烟雾(或者更确切地说,被全新映像替代)。在构建新映像的过程中,exec*将复制argv数组(和环境数组)到其中。无论如何,将永远不会调用std::vectorstd::string析构函数。

另一方面,如果execvp失败,则传递给它的参数将不会被修改。 (POSIX:“指针的argv[]envp[]阵列和串到这些阵列点不得通过调用修改以exec函数之一,除非更换处理图像的结果。”)

在无论哪种情况,都不需要复制字符串。您可以使用std::string::c_str()来提取指向底层C字符串的指针(作为const char*,但请参阅下文)。其次,如果您使用的是C++ 11或更新的版本,std::vector可方便地附带data()成员函数,该函数返回指向底层存储的指针。因此,如果您有std::vector<char*> svec,那么svec.data()将作为底层char*[],这是您想要传入execvp的内容。

所以,问题降低到创建从std::vector<std::string>,这是简单的一个std::vector<char*>

else if (kidpid == 0) { 
    // I am the child. 
    std::vector<char*> argc; 
    // const_cast is needed because execvp prototype wants an 
    // array of char*, not const char*. 
    for (auto const& a : args) 
     argc.emplace_back(const_cast<char*>(a.c_str())); 
    // NULL terminate 
    argc.push_back(nullptr); 
    // The first argument to execvp should be the same as the 
    // first element in argc, but we'll assume the caller knew 
    // what they were doing, and that program is a std::string. 
    execvp(program.c_str(), argc.data()); 
    // It's not clear to me what is returning here, but 
    // if it is main(), you should return a small positive value 
    // to indicate an error 
    return 1; 
} 
+0

有'std :: vector argc',不需要const转换。 –

+0

@nm:那么argc.data是'const char * []'这不是'execvp'的正确原型(TIAS:“错误:从'const char **'无效转换为'char * const *'[ fpermissive]“) – rici

+0

嗯,是的。我的印象是,execvp的参数是'const char * const *'。但是,不,这个原型在C中工作不太好。太糟糕了! –