c_str() 的生命周期是否在 g++ 4.8.4 和 g++ 5.3.1 之间发生了变化?
Did the lifetime of c_str() changed between g++ 4.8.4 and g++ 5.3.1?
我从一个守护进程启动进程,它确保所述进程 运行 连续并以正确的顺序启动,等等。
在某些时候,我想用 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 编译的相同代码时,c_str()
指针失效.1.
根据我的理解,这不应该是因为我没有修改创建裸指针数组的第一个循环和 execv()
调用之间的字符串。
reference 说:
The pointer obtained from c_str() may be invalidated by:
- Passing a non-const reference to the string to any standard library function, or
- Calling non-const member functions on the string, excluding operator[], at(), front(), back(), begin(), rbegin(), end() and rend().
P.S. 我已经有了一个修复,我现在对 c_str()
做了一个 stdup()
,这样就可以正常工作了.只有我希望尽可能避免字符串的一个额外副本...
这里有两个问题:
for(auto a : args)
{
args_p.push_back(a.c_str());
}
首先,c_str()
returns一个char const*
而args_p
是一个vector<char*>
。由于您需要指向非 const
char
的指针,因此您将不得不使用 &a[0]
。
其次,a
在循环的每次迭代结束时超出范围。所以你抓住的指针会从你下面被摧毁。您需要指向 args
中实际字符串的指针 - 因此您需要通过引用进行迭代:
for(auto& a : args)
{
args_p.push_back(&a[0]);
}
我从一个守护进程启动进程,它确保所述进程 运行 连续并以正确的顺序启动,等等。
在某些时候,我想用 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 编译的相同代码时,c_str()
指针失效.1.
根据我的理解,这不应该是因为我没有修改创建裸指针数组的第一个循环和 execv()
调用之间的字符串。
reference 说:
The pointer obtained from c_str() may be invalidated by:
- Passing a non-const reference to the string to any standard library function, or
- Calling non-const member functions on the string, excluding operator[], at(), front(), back(), begin(), rbegin(), end() and rend().
P.S. 我已经有了一个修复,我现在对 c_str()
做了一个 stdup()
,这样就可以正常工作了.只有我希望尽可能避免字符串的一个额外副本...
这里有两个问题:
for(auto a : args)
{
args_p.push_back(a.c_str());
}
首先,c_str()
returns一个char const*
而args_p
是一个vector<char*>
。由于您需要指向非 const
char
的指针,因此您将不得不使用 &a[0]
。
其次,a
在循环的每次迭代结束时超出范围。所以你抓住的指针会从你下面被摧毁。您需要指向 args
中实际字符串的指针 - 因此您需要通过引用进行迭代:
for(auto& a : args)
{
args_p.push_back(&a[0]);
}