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

为何指向int紧邻内存地址的指针操作仅在偏移3个int时生效?

为什么指针偏移量不同会导致程序运行结果差异?

问题描述

我尝试将指针指向int类型数值的紧邻内存地址,并为该地址写入原数值的两倍。但仅当内存偏移量为3(即3*4,int的大小)或更大时程序才能正常运行,若将偏移量降至2或1,程序无任何输出(出现错误)。

可正常运行的代码:

#include <stdio.h>
int main(){
    int x, *ptr, memory_jump = 3;
    scanf("%d",&x);
    ptr = &x+memory_jump;
    *ptr = x * 2;
    printf("Given int = %d, Address = %d \nNext address content = %d,Next address pos = %d",x,&x,*ptr,ptr);
    return 0;
}

出现错误的代码:

int main(){
    int x, *ptr, memory_jump = 2;
    scanf("%d",&x);
    ptr = &x+memory_jump;
    *ptr = x * 2;
    printf("%d", (ptr-2));
    printf("Given int = %d, Address = %d \nNext address content = %d,Next address pos = %d",x,&x,*ptr,ptr);
    return 0;
}

请问这两个紧邻内存地址发生了什么情况?


问题解答

首先得给你敲个警钟:你遇到的是C语言中典型的未定义行为——不管偏移量是1、2还是3,这种跨出变量合法内存范围的指针操作都是严格违反C语言标准的,所谓“能正常运行”只是偶然的运气,完全不可靠。

咱们一步步拆解背后的逻辑:

  • 单个int x在栈上占用4字节(假设你的系统中int是4字节),对于指向它的指针&x,C语言只允许你访问两个合法位置:&x(指向x本身)和&x+1(指向x末尾的下一个位置,只能指向但不能解引用)。任何超过这个范围的偏移(比如&x+2、&x+3)都属于越界内存访问。
  • 当你执行*ptr = x * 2时,你在往不属于当前变量的内存地址写入数据,最终结果完全取决于那个地址存储的内容:
    • 偏移量为3时,ptr指向的地址刚好是栈上一块“闲置”的、当前进程有权限修改的区域,而且没有覆盖程序运行的关键数据(比如main函数的返回地址、栈帧的控制信息、其他局部变量),所以程序侥幸完成了所有操作并输出结果。但这完全是随机的——换个编译器、操作系统,甚至同一台电脑多次运行,都可能直接崩溃。
    • 偏移量为1或2时,ptr指向的是栈上的关键区域:可能是scanf函数的临时参数、main函数栈帧的返回地址,或者栈帧的其他控制结构。你往这里写入数据直接破坏了程序的执行逻辑,导致程序还没走到printf语句就崩溃了,自然看不到任何输出。

关键结论:这种行为没有固定规律,完全是未定义行为的随机性导致的。永远不要编写依赖这种“碰巧能跑”的代码,这是C语言编程中必须避免的危险操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:35:04