You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何循环第二次调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:22:43