如何以可靠的方式将std::vector转换为char**



我一直在努力避免使用char**数组,但由于我使用的是execvp,我编写了一个方法将字符串向量转换为以null结尾的char**。

不幸的是,直到最近我还遇到了分割错误,这让我怀疑我的方法并不总是有效,原因是这样或那样的:

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;
}

如果我一开始就可以完全摆脱char**,那将是理想的。为什么这个代码是分段的?

编辑:我就是这么称呼它的:

char **argvA;
vectorToNullArray(_ARGV, argvA);

其中_ARGV是某个类的成员变量std::vector<std::string>

编辑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;
}

与execvp:一起使用

std::vector<char *> argv = nullTerminatedArgV(_ARGV);
char **command = argv.data();
int status = execvp(command[0], command);
perror("execvp error");

基本上是公认的答案,从这里添加:

https://stackoverflow.com/a/47714627/5133238

正如Pete Becker所说,问题可能是您没有正确地调用它,特别是a参数没有指向足够大的char*数组。

不管怎样,你真的需要在这里搞动态内存分配吗?让std::vector为您管理内存更容易、更安全、更简洁。也许您可以执行以下操作,然后将结果的.data()值传递给execvp?您确实需要确保作为参数传递的字符串向量在该调用之后和调用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);

CCD_ 9具有一定的随机值;将其传递给CCD_ 10会导致未定义的行为。

该代码不分配数组本身,而是为其分配值

最新更新