为execvp()创建char * const *

时间:2016-02-13 23:56:52

标签: c++

在满足execvp的第二个参数方面遇到很多麻烦。编译器说它需要一个char * const *传递给我有一个const char **。我希望它来自用户输入:

std::string x;
std::cout<<" [CMD]: ";
getline(std::cin, x);
const char** args = fillArgs(x);
execvp(args[0], args);

fillArgs的代码是将字符串转换为动态分配的指向字符数组的指针。简而言之,它看起来像这样:

const char** fillArgs(std::string currentCMD)
{
     //Above this, the string passed into the function is split into substrings separated
    //by whitespaces and each is placed into the string vector called input.

    const char** command = new const char*[SIZE];
    for(int i = 0; i < SIZE; i++)
    {
        command[i] = input[i].c_str();
    }
    return command;
}

我知道它需要以nullpointer结束并在上面的代码中处理它。建议?

2 个答案:

答案 0 :(得分:2)

char* const argv[](和char* const *argv)是指向可变const数组的char指针数组。 (即使execvp可能不会修改字符串)。

但是const char** args(与char const** args相同)是一组指向const char数组的可变指针。

std::string::c_str返回指向const char*数组的const char指针。但是execvp需要可变的char数组。

一种解决方案是使用const_cast

const char* command = input[i].c_str();
char* command_mutable = const_cast<char*>(command);

char* const *argv;
argv[i] = command_mutable;

这适用于execvp,因为它只读取字符串并复制它们以供新的可执行文件使用,并且不会返回。对于可以修改字符串并正常返回的函数,它是未定义的行为。

但另一个问题是c_str返回的指针只有std::string对象存在才有效。函数fillArgs不正确,因为当它返回返回值中的指针时无效。 (如果它是在堆栈上分配的话,也是command数组本身。)

所以这会奏效:

std::string str = "example";
char* const args[3];
args[1] = const_cast<char*>(str.c_str());
args[2] = nullptr;
execvp(args[0], args);
// Not the other program is running

当使用可以修改数组的execvp以外的其他函数时,最好为函数创建一个临时数组:

std::string str = "example";
std::unique_ptr<char[]> tmp_str(new char[str.size() + 1]);
std::memcpy(tmp_str.get(), str.c_str(), str.size() + 1);
char* const args[3];
args[1] = tmp_str.get();
args[2] = nullptr;
something(args[0], args);
tmp_str.reset(); // release the temporary memory

答案 1 :(得分:0)

好吧,在execvp not working when converting from vector<string> to vector<char*> to char**引起我的注意后,我又回到了使用那个字符串向量。这种方式更有效,更容易阅读我的代码。我错过了.data()函数。