为何循环第二次调用execv系统调用崩溃,第一次却成功?
C++ execv调用失败(Errno 14)问题分析与修复
问题本质
execv的第二个参数argv严格要求是以NULL指针结尾的字符指针数组,这是POSIX标准的硬性规定。你的代码里args_ptrs只存储了args中的两个字符串指针,没有添加末尾的NULL,导致execv访问非法内存地址,触发EFAULT(错误码14)。
那些看似能解决问题的操作(改字符串长度、调整reserve大小)只是巧合:
- 当用
std::string(16, 'a')时,栈内存恰好给args_ptrs数组后面补了一个零值,execv误打误撞能运行; - 把
reserve大小改成args.size()+2时,vector预留的额外内存可能被初始化为零,同样让execv误以为数组有正确的结尾。但这些都是不可靠的运气,不是正确解法。
正确修复代码
修改SetUpSlave函数,必须显式在args_ptrs末尾添加NULL指针:
void SetUpSlave(std::string path) { std::vector<char*> args_ptrs; // 预留足够空间,避免内存重新分配 args_ptrs.reserve(args.size() + 1); for (const auto& arg : args) { args_ptrs.push_back(const_cast<char*>(arg.data())); } // 强制添加NULL作为数组结尾,满足execv要求 args_ptrs.push_back(nullptr); execv(path.data(), args_ptrs.data()); cerr << "Errno value: " << errno << endl; assert(false); }
补充说明
- 使用
const_cast<char*>是安全的:POSIX标准明确exec族函数只会读取argv的内容,不会修改字符串; - 永远不要依赖内存布局的巧合,显式添加NULL才能保证代码在不同系统、不同编译环境下稳定运行。
内容的提问来源于stack exchange,提问作者PaRat07
相关产品推荐
相关产品推荐

