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

小端序与内存覆盖:一段UB的C++代码运行原理解析

越界访问C++代码的运行机制解析

首先明确:这段代码属于未定义行为(UB),因为它访问了数组x的越界元素x[3]。我们基于「编译器将全局变量连续排布、无额外优化」的假设场景,拆解其运行逻辑:

#include <stdio.h>

int x[] = {1, 2, 3};
char s[] = "hello";

int main()
{
    puts(s);
    x[3] = ('e' << 16) + ('y' << 8) + 'b';
    puts(s);
}

1. 假设非UB场景,内存中发生了什么,为何输出bye?

  • 全局变量x和s在程序的全局数据段中连续排布(此处x在前,s在后)。
  • x是包含3个int元素的数组,在32位系统中每个int占4字节,因此x共占用12字节内存。x[3]属于越界访问,对应的内存地址恰好是s数组的起始位置。
  • 赋值语句计算后,得到的int值结构为:高8位是0,次高8位是'e'的ASCII码(101),中间8位是'y'的ASCII码(121),低8位是'b'的ASCII码(98)。这个int值的4个字节会被写入s数组的起始地址,覆盖s的前4个字节。

2. 为何bye的'e'后会自动插入空终止符?

  • 原s数组的内容是'h' 'e' 'l' 'l' 'o' '\0'(共6字节)。
  • 写入的int值的最高8位为0,在小端模式下,这个0字节会被存在s[3]的位置,刚好是字符串的空终止符'\0'。当puts函数输出时,遇到该终止符就会停止输出,因此最终显示bye。

3. 大小端序在此过程中起到了什么作用?

  • 大小端直接决定了int类型数据在内存中的字节存储顺序:
    • 小端模式(x86架构主流):int的低字节存储在低地址,高字节存储在高地址。因此赋值的int字节会按'b'、'y'、'e'、0的顺序依次写入s[0]到s[3],形成'b' 'y' 'e' '\0'的有效字符串,最终输出bye。
    • 大端模式:int的高字节存储在低地址,此时s[0]会被写入0,puts会直接输出空字符串,无法得到bye的结果。可见这段代码能输出bye完全依赖系统是小端序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:00:25