我从一个守护进程启动进程,确保所述进程连续运行并以正确的顺序开始,等等。
在某些时候,我想用execv()
启动进程,所以我为参数准备了一个字符串数组:
std::vector<std::string> args;
args.push_back("--debug");
args.push_back("--connect");
args.push_back("10.0.0.5:4040");
...
在大多数情况下,我有大约10个这样的论点。
现在,execv()
只访问一个裸指针数组。所以我执行以下操作来创建这样的指针数组:
std::vector<char *> args_p; // sorry, my code actually uses std::vector<char const *> args_p -- so constness is fine here
for(auto a : args)
{
args_p.push_back(a.c_str());
}
args_p.push_back(nullptr); // list needs to be null terminated
然后我可以用最后一个数组调用execv()
:
execv(
args_p[0],
const_cast<char * const *>(&args_p[0])
);
这在Ubuntu 14.04中使用g ++ 4.8.4完美地工作,但不知何故,当我尝试运行使用g ++ 5.3.1编译的相同代码时,c_str()
指针无效。
根据我的理解,这不应该是因为我不修改创建裸指针数组的第一个循环和execv()
调用之间的字符串。
从c_str()获得的指针可以通过以下方式无效:
- 将对字符串的非const引用传递给任何标准库函数,或
- 在字符串上调用非const成员函数,不包括operator [],at(),front(),back(),begin(),rbegin(),end()和rend()。
P.S。我已经有了修复,我现在执行了stdup()
的{{1}},这样就可以了。只有我希望在可能的情况下避免使用一个额外的字符串副本......
答案 0 :(得分:2)
这里有两个问题:
for(auto a : args)
{
args_p.push_back(a.c_str());
}
首先,c_str()
返回char const*
,args_p
为vector<char*>
。由于您需要指向非const
char
的指针,因此您必须使用&a[0]
。
其次,a
在循环的每次迭代结束时超出范围。所以你所掌握的指针会从你身下被摧毁。你需要指向args
中实际字符串的指针 - 所以你需要通过引用迭代:
for(auto& a : args)
{
args_p.push_back(&a[0]);
}