为何这段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
相关产品推荐
相关产品推荐

