How to pass a vector to execvp

2020-02-14 09:08发布

问题:

I want to pass a vector in as the second argument to execvp. Is it possible?

回答1:

Not directly; you'd need to represent the vector as a NULL-terminated array of string pointers somehow. If it's a vector of strings, that is straightforward to do; if it's some other kind of data you would have to figure how to encode it as strings.



回答2:

Yes, it can be done pretty cleanly by taking advantage of the internal array that vectors use.

This will work, since the standard guarantees its elements are stored contiguously (see https://stackoverflow.com/a/2923290/383983)

#include <vector>

using namespace std;

int main(void) {
  vector<char *> commandVector;

  // do a push_back for the command, then each of the arguments
  commandVector.push_back("echo");
  commandVector.push_back("testing");
  commandVector.push_back("1");
  commandVector.push_back("2");
  commandVector.push_back("3");  

  // push NULL to the end of the vector (execvp expects NULL as last element)
  commandVector.push_back(NULL);

  // pass the vector's internal array to execvp
  char **command = &commandVector[0];

  int status = execvp(command[0], command);
  return 0;
}


回答3:

Yes, it can be done pretty cleanly by taking advantage of the internal array that vectors use.

This will work, since the standard guarantees its elements are stored contiguously (see https://stackoverflow.com/a/2923290/383983)

#include <vector>

using std::vector;

int main() {
  vector<char*> commandVector;

  // do a push_back for the command, then each of the arguments
  commandVector.push_back(const_cast<char*>("echo"));
  commandVector.push_back(const_cast<char*>("testing"));
  commandVector.push_back(const_cast<char*>("1"));
  commandVector.push_back(const_cast<char*>("2"));
  commandVector.push_back(const_cast<char*>("3"));

  // push NULL to the end of the vector (execvp expects NULL as last element)
  commandVector.push_back(NULL);

  int status = execvp(command[0], &command[0]);
  return 0;
}

Do a const_cast to avoid the "deprecated conversion from string constant to 'char*'". String literals are implemented as 'const char*' in C++. const_cast is the safest form of cast here, as it only removes the const and does not do any other funny business. execvp will not edit the values anyway.

If you want to avoid all casts, you have to complicate this code by copying all the values to 'char*' types not really worth it.