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

C++数组内存分配地址选择及指针赋值后地址异常咨询

你的两个C++内存疑惑解答

一、数组地址间隔16字节不是防越界措施,是内存对齐与栈布局规则导致的

首先得明确:编译器给栈上变量分配地址时,核心考虑的是内存对齐(Memory Alignment)和栈帧的布局优化,不是为了防止数组越界。

你看到的两个数组地址相差16字节,大概率是这几个原因:

  • 内存对齐要求:现代CPU访问内存时,对于int这类基础数据类型,通常要求地址是其大小的整数倍(比如int是4字节,地址要能被4整除;部分平台的double则要求8字节对齐)。编译器会在变量之间自动填充空白字节(padding),保证每个变量都满足对齐要求。
  • 栈的增长方向:多数平台的栈是从高地址向低地址增长的,后定义的变量地址会比先定义的更低。如果你的两个数组大小加上必要的padding刚好凑成16字节的间隔,就会出现这种情况。
  • 栈帧优化:编译器可能会把变量按大小或类型分组,优化内存使用,这也可能导致变量之间出现额外的间隔。

而防止数组越界的措施,通常是编译时的静态检查(比如编译器报错数组下标越界),或者运行时的工具(比如AddressSanitizer),和数组之间的地址间隔没有直接关系。

二、修改指针指向不会改变数组本身的内存地址

先看你贴的代码和输出:

// more pointers
#include <iostream>
#include <string>
using namespace std;
int main () {
 int numbers[5]={1,2,3,4,5};
 int alien=6;
 int * a;
 int * b;
 b=numbers;  // b指向numbers数组的首地址
 a=&alien;    // a指向alien的地址
 b=a;         // 修改b的指向,现在b指向alien
 cout << "address of start of array numbers: " << b << endl;
 cout << "address of alien: " << a << endl;
 for (int i=0;i<5;i++){
 cout << &numbers[i] << endl;
 cout << numbers[i] << endl;
 }
 return 0;
}

输出:

address of start of array numbers: 0x79ab503a591c
address of alien: 0x79ab503a591c
0x79ab503a5920 1
0x79ab503a5924 2
0x79ab503a5928 3
0x79ab503a592c 4
0x79ab503a5930 5

这里的关键误区是:指针b只是一个用来存储地址的变量,它和数组numbers本身是完全独立的。

你做了b=a这一步,只是把b里面存储的地址值改成了alien的地址,但这并不会对numbers数组产生任何影响:

  • numbers数组的内存是在程序进入main函数时,就被编译器分配在栈上的固定位置了,它的地址从一开始就确定了,不会因为你修改某个指针的指向而改变。
  • 你遍历&numbers[i]时,输出的是数组元素本身的内存地址,自然还是原来的固定地址;而numbers[i]的值也没有被修改,所以输出的还是初始化的1-5。

简单说:指针就像一张写着地址的纸条,你修改纸条上的地址,并不会改变原来房子(数组)的位置,只是纸条现在指向了另一栋房子(alien)而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:32:17