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

为何这段C代码无输出且退出状态为-1?

问题解析与解决

核心问题:直接访问物理地址0xA000000属于非法操作

现代Windows/Linux/macOS等系统都采用虚拟内存机制,用户态程序根本没有权限直接访问物理地址0xA000000。你强行通过指针写入这个地址,会立刻触发内存访问错误(段错误/访问违规),操作系统会直接终止程序运行——这就是退出状态为-1的原因,程序还没走完流程就异常崩溃了,没执行到正常的return 0步骤。

为什么没有输出?

printf的输出默认是缓冲机制,程序崩溃时,缓冲区里的内容还没来得及刷新到终端,所以你看不到任何输出。如果要验证这个逻辑,可以在printf后加一句fflush(stdout);强制刷新缓冲区,但这也救不了崩溃的程序,只能帮你确认:如果程序正常运行,这句会让内容立刻输出。

关于「远指针/长指针」的误解

你提到的far关键字是DOS时代16位C编译器(比如Turbo C)的产物,用来突破当时64KB内存段的限制。现在的32/64位系统采用平坦内存模型,根本不存在far指针的概念,给指针加long修饰完全没用——unsigned long int*只是表示指针指向的是unsigned long int类型的数据,和指针本身的长度、寻址范围没有关系(32位系统指针固定4字节,64位系统固定8字节)。

想操作VGA显存怎么办?

0xA0000确实是DOS下VGA 256色模式的显存物理地址,但现在的系统早就抛弃了这种直接访问的方式:

  • 如果你用Linux,可以通过/dev/fb0帧缓冲设备操作显存,需要用open/read/write系统调用,且需要root权限。
  • 如果你用Windows,得借助GDI、DirectX或Win32 API来操作显示设备,不能直接写物理地址。
  • 要是想体验DOS时代的显存操作,可以安装DOSBox模拟器,搭配Turbo C这类老编译器写代码,那时直接访问0xA0000才会生效。

修正后的测试代码(验证输出逻辑)

如果只是想测试printf能否正常输出,删掉非法内存写入的代码即可:

#include <stdio.h>

int main(void) {
    unsigned long int *a;
    printf("%p\n", &a);
    fflush(stdout); // 强制刷新输出缓冲区
    return 0;
}

这段代码能正常运行,输出变量a的地址,程序退出状态为0。

内容的提问来源于stack exchange,提问作者Cishard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:39:56