2016-02-06 99 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中工作不太好。太糟糕了! –