我在c++程序中遇到这个问题
#include <bits/stdc++.h>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;
std::vector<std::string> args;
void SetUpSlave(std::string path) {
std::vector<char*> args_ptrs;
args_ptrs.reserve(args.size());
for (int i = 0; i < args.size(); ++i) {
args_ptrs.push_back(args[i].data());
}
execv(path.data(), args_ptrs.data());
cerr << "Errno value: " << errno << endl;
assert(false);
}
int main() {
int status;
for (int i = 0; i < 2; ++i) {
args = { "/usr/bin/echo", "MESSAGE" };
pid_t slave_pid = fork();
if (slave_pid) {
assert(waitpid(slave_pid, &status, 0) != -1);
} else {
SetUpSlave("/usr/bin/echo");
}
std::string(17, 'a');
}
return 0;
}
为什么这段代码会失败并输出:
MESSAGE
Errno value: 14
test: /tmp/tmp.9dU24JfFL4/main.cpp:17: void SetUpSlave(std::string): Assertion `false' failed.
此问题发生在 ubuntu 24.04 和 g++ 13.2.0 上
如果我改变 std::string(17, 'a');到 std::string(16, 'a');错误消失。
还有助于更改 args_ptrs.reserve(args.size());到 args_ptrs.reserve(args.size() + 2);
execv
需要一个以 null 结尾的字符串数组,这意味着最后一个 char*
元素是 NULL
。
您应该使用
std::string::c_str()
,而不是 data()
,因为前者是空终止的。
void SetUpSlave(std::string path) {
std::vector<char*> args_ptrs;
args_ptrs.reserve(args.size()+1);
for (int i = 0; i < args.size(); ++i) {
args_ptrs.push_back(args[i].c_str()());
}
args_ptrs.push_back(nullptr); // Add null termination
execv(path.data(), args_ptrs.data());
cerr << "Errno value: " << errno << endl;
assert(false);
}