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

C++编译运行的子程序返回的数组指针能否被跨进程直接访问?

结论

直接访问编译生成的子程序输出的数组首地址,必然触发段错误,完全不具备可行性。

核心原因
  • 所有现代操作系统都会对用户态进程做强制的虚拟地址空间隔离:每个进程持有的内存地址都是独立的虚拟地址,不是真实物理内存地址。你从子程序输出拿到的数组首地址,是子程序自身虚拟地址空间内的栈上地址,和父进程的虚拟地址空间没有任何映射关联。父进程直接访问这个地址,要么命中未分配的内存页触发段错误,要么读到自身地址空间内对应位置的无关垃圾值。
  • 父子进程之间不存在内存访问特权:就算子程序是当前进程编译、拉起的,操作系统的进程隔离规则也不会有任何豁免。进程隔离是内核层面强制执行的安全机制,和进程的创建来源、运行权限无关,即便是root权限运行的父进程,也不能直接裸访问其他进程的私有内存。
  • 示例代码中的数组是main函数栈帧上的局部变量,生命周期完全依附于子程序的main函数栈,就算是同一个进程内,只要main函数返回该地址就会成为野指针,跨进程场景下更不可能合法访问。
跨进程高性能消息传递的正确方案

不存在完全不借助系统API就能跨进程共享内存的实现。如果要实现零拷贝的高性能数组传递,正确方案是使用操作系统提供的共享内存机制:

  1. 父进程创建共享内存段,获取对应的内存句柄
  2. 启动子程序时将共享内存句柄传递给子程序
  3. 两个进程将同一块共享内存映射到各自的虚拟地址空间,之后就可以像访问进程内内存一样读写这块内存,没有额外拷贝开销,性能最高。

你当前的实现逻辑完全没有做共享内存映射,本质是两个完全独立的进程:

std::string code = R"( 
   #include<thread>
   #include<iostream>
   int main() 
   { 
       int array[@@size@@]; 
       std::cout<<(size_t)&array[0]<<std::endl;
       std::this_thread::sleep(1000000000);
       return 0; 
   } 
)";

boost::replace_all(code, "@@size@@", std::to_string(memSize));

对应的编译命令也没有处理内存共享相关逻辑:

system("g++ code.cpp");

补充:如果不做共享内存映射,也可以通过系统提供的进程内存调试接口(比如Linux下的process_vm_readv/process_vm_writev、ptrace接口)读写其他进程内存,但这类接口有额外的调用开销,性能远低于共享内存,也不属于“无API直接访问”的范畴。


内容的提问来源于stack exchange,提问作者huseyin tugrul buyukisik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 16:18:20