在满足 execvp 的第二个参数时遇到了很多麻烦。编译器说它需要在我有 const char** 的地方传递一个 char* const*。我更喜欢它由用户输入制成:
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;
}
我知道它需要以空指针结束并在上面的代码中处理了这一点。有什么建议吗?
最佳答案
char* const argv[]
(和 char* const *argv
)是指向可变 char 的
数组。 (即使 const
指针数组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
关于c++ - 为 execvp() 创建一个 char* const *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35386791/