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

C语言跨进程访问内存为何触发Segmentation Fault?

为什么直接使用另一个进程的指针地址会触发Segmentation Fault?

这个问题的核心在于现代操作系统的进程地址空间隔离机制,咱们一步步拆解原因:

1. 每个进程的虚拟地址空间是完全独立的

现代操作系统(比如Linux、Windows)都采用了虚拟内存机制,每个运行的进程都会获得一套属于自己的虚拟地址空间。这意味着:

  • 第一个程序里输出的0x7ffebbd57fc8只是它自身进程的虚拟地址,这个地址在第二个进程的地址空间里,要么没有映射到任何物理内存,要么你没有访问权限。
  • 当第二个进程尝试访问这个地址时,操作系统会检测到非法内存访问,直接触发Segmentation Fault终止程序。

2. 你混淆了「指针变量的地址」和「指针指向的内存地址」

仔细看第一个程序的代码:

printf(" foo addr : %p\n\n" ,&foo);

这里你打印的是指针变量foo本身在栈上的地址,而不是foo指向的、通过malloc分配的堆内存地址。如果你的目的是想访问malloc出来的那个存着s的内存,你应该打印foo而不是&foo:

printf(" foo points to : %p\n\n" , foo); // 这才是堆内存的地址

但就算你拿到了堆内存的地址,第二个进程依然无法访问——因为那块堆内存属于第一个进程的地址空间,第二个进程没有权限触碰。

3. 跨进程访问内存的正确姿势

如果需要在两个进程间共享数据,不能直接硬编码地址,必须使用操作系统提供的跨进程通信(IPC)机制,比如:

  • 共享内存:Linux下用shmget/shmat系列函数,Windows下用CreateFileMapping
  • 管道:匿名管道或命名管道
  • 消息队列
  • 套接字(即使是本地进程也可以用Unix域套接字)
    这些机制由操作系统协调,能保证内存访问的合法性和安全性。

举个修正后的第一个程序例子(只是纠正地址打印问题,依然不能跨进程访问):

#include <stdio.h>
#include <stdlib.h>
int main(){
    char* foo=(char*) malloc(1);
    *foo='s';
    printf(" foo points to : %p\n\n" , foo); // 打印指向的堆内存地址
    int pause;
    scanf("%d",&pause);
    free(foo); // 记得释放malloc的内存
    return 0;
}

内容的提问来源于stack exchange,提问作者Seçkin Güleviz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:45:10