[英]how do i convert std::vector to char ** in a reliable way?
I have been trying to avoid using char ** arrays, however because i am using execvp, i wrote a method to convert a vector of strings to a null terminated char **.我一直在尝试避免使用 char ** 数组,但是因为我使用的是 execvp,所以我编写了一个方法将字符串向量转换为空终止的 char **。
Unfortunately i have until recently been getting segmentation faults, which makes me suspicious that my method doesn't always work for one reason or another:不幸的是,直到最近我才遇到分段错误,这让我怀疑我的方法由于某种原因并不总是有效:
void vectorToNullArray(std::vector<std::string> const &v, char **a) {
int i = 0;
while (i < v.size()) {
std::string str = v[i];
char *cstr = new char[str.size()+1];
strcpy(cstr, str.c_str());
a[i] = cstr; // <-- segfault here
i++;
}
a[i] = nullptr;
}
if i can be completely free of char ** in the first place, that would be ideal.如果我首先可以完全摆脱 char **,那将是理想的。 Why is this code segfaulting?
为什么这段代码会出现段错误?
EDIT: this is how i call it:编辑:这就是我所说的:
char **argvA;
vectorToNullArray(_ARGV, argvA);
where _ARGV
is an std::vector<std::string>
, a member variable of some class.其中
_ARGV
是std::vector<std::string>
,某个类的成员变量。
EDIT 2: working solution编辑 2:工作解决方案
std::vector<char *> nullTerminatedArgV(std::vector<std::string> const &v) {
std::vector<char *> result;
for (auto const &s : v) {
result.push_back(const_cast<char *>(s.c_str()));
}
result.push_back(nullptr);
return result;
}
usage with execvp:与 execvp 一起使用:
std::vector<char *> argv = nullTerminatedArgV(_ARGV);
char **command = argv.data();
int status = execvp(command[0], command);
perror("execvp error");
essentially the accepted answer, with additions from here:基本上是公认的答案,从这里补充:
https://stackoverflow.com/a/47714627/5133238 https://stackoverflow.com/a/47714627/5133238
As Pete Becker says, the issue's probably that you haven't called it properly - and specifically that the a
argument doesn't point to a sufficiently large array of char*
s to write to.正如皮特贝克尔所说,问题可能是你没有正确调用它 - 特别是
a
参数没有指向足够大的char*
数组来写入。
Anyway, do you really need to screw around with dynamic memory allocation here?无论如何,您真的需要在这里进行动态内存分配吗? Having
std::vector
manage memory for you is much easier, safer, and more concise.让
std::vector
为您管理内存更容易、更安全、更简洁。 Perhaps you can do something like below, then pass the result's .data()
value to execvp
?也许您可以执行以下操作,然后将结果的
.data()
值传递给execvp
? You do need to make sure the vector of strings passed as an argument is not mutated by the caller after this call and before calling execvp
, otherwise the pointers you collect may be invalidated.您确实需要确保在此调用之后和调用
execvp
之前,作为参数传递的字符串向量不会被调用者改变,否则您收集的指针可能会失效。
std::vector<const char*> getVectorOfPointersToStrings(std::vector<std::string> const& v) {
std::vector<const char*> result;
for (const auto& s : v)
result.push_back(s.c_str());
result.push_back(nullptr);
return result;
}
char **argvA;
vectorToNullArray(_ARGV, argvA);
argvA
has some random value; argvA
有一些随机值; passing it to vectorToNullArray
results in undefined behavior.将它传递给
vectorToNullArray
导致未定义的行为。
The code doesn't allocate the array itself, but assigns values to it.代码不会分配数组本身,而是为其分配值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.