在栈中连续的变量地址为什么差了C?也就是12

XGHeaven 2014-08-12 10:32:54
我用这个程序测试的,用VS2013
	#include <iostream>
using namespace std;

int a;

int main() {
int b;
int c;
int d;
int e;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
cout << &e << endl;
cout << sizeof(int) << endl;
return 0;
}

但输出的结果是,第二个一直到第五个每两个之间小了一个C,也就是12,但是INT不是占用4个字节么?那为什么会少12个字节呢?请问这是怎么回事?
...全文
405 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
但是GV但是 2014-08-13
  • 打赏
  • 举报
回复
因为你是从下往上做减法的,并且没有借位
赵4老师 2014-08-13
  • 打赏
  • 举报
回复
编译器的命令行选项都有哪些,作用都是什么,这些知识补一补。
www_adintr_com 2014-08-13
  • 打赏
  • 举报
回复
DEBUG 版为了在变量访问越界的时候做出检测,在变量之间插入了一些填固定值的内容
mymtom 2014-08-13
  • 打赏
  • 举报
回复
DEBUG版本有调试信息,RELEASE版本的间隔就是4啦
我看你有戏 2014-08-13
  • 打赏
  • 举报
回复
这样定义,不一定连续的啊
难题 2014-08-13
  • 打赏
  • 举报
回复
这与各个编译器有关的,不同的编译器也是不一样的
wanght99 2014-08-13
  • 打赏
  • 举报
回复
引用 4 楼 XGHeaven 的回复:
[quote=引用 1 楼 wanght99 的回复:] 可能是编译器优化,16字节对齐,提升内存效率的。你看看地址是不是都是16的倍数
没有,都相差12,也就是12的倍数[/quote] 12是比较奇怪, 在下想不到合理的解释, 不过编译器怎么为变量分空间是编译器的自由, 没有要求在一块声明的变量一定要在一块, , 写程序的时候也不能对两个变量间的距离作任何假设.
赵4老师 2014-08-13
  • 打赏
  • 举报
回复
引用 14 楼 XGHeaven 的回复:
[quote=引用 11 楼 zhao4zhong1 的回复:] 编译器的命令行选项都有哪些,作用都是什么,这些知识补一补。
这跟命令行有什么关系?[/quote] IDE编译的时候是调用命令行编译器cl.exe的。
                         C/C++ 编译器选项


                              -优化-

/O1 最小化空间                          /O2 最大化速度
/Ob<n> 内联扩展(默认 n=0)               /Od 禁用优化(默认)
/Og 启用全局优化                        /Oi[-] 启用内部函数
/Os 优选代码空间                        /Ot 优选代码速度
/Ox 最大化优化                          /Oy[-] 启用帧指针省略

                             -代码生成-

/GF 启用只读字符串池                    /Gm[-] 启用最小重新生成
/Gy[-] 分隔链接器函数                   /GS[-] 启用安全检查
/GR[-] 启用 C++ RTTI                    /GX[-] 启用 C++ EH (与 /EHsc 相同)
/EHs 启用 C++ EH (没有 SEH 异常)        /EHa 启用 C++ EH (w/ SEH 异常)
/EHc 外部“C”默认为 nothrow
/fp:<except[-]|fast|precise|strict> 选择浮点模式:
    except[-] - 在生成代码时考虑浮点异常
    fast -“fast”浮点模式;结果可预测性比较低
    precise -“precise”浮点模式;结果可预测
    strict -“strict” 浮点模式(意味着 /fp:except)
/GL[-] 启用链接时代码生成               /GA 为 Windows 应用程序进行优化
/Ge 对所有函数强制堆栈检查              /Gs[num] 控制堆栈检查调用
/Gh 启用 _penter 函数调用               /GH 启用 _pexit 函数调用
/GT 生成纤程安全 TLS 访问               /RTC1 启用快速检查(/RTCsu)
/RTCc 转换为较小的类型检查              /RTCs 堆栈帧运行时检查
/RTCu 未初始化的局部用法检查
/clr[:option] 为公共语言运行库编译,其中 option 是:
    pure - 生成只包含 IL 的输出文件(没有本机可执行代码)
    safe - 生成只包含 IL 的可验证输出文件
    oldSyntax - 接受 Visual C++ 2002/2003 的托管扩展语法
    initialAppDomain - 启用 Visual C++ 2002 的初始 AppDomain 行为
    noAssembly - 不产生程序集           /Gd __cdecl 调用约定
/Gr __fastcall 调用约定                 /Gz __stdcall 调用约定
/GZ 启用堆栈检查(/RTCs)                 /QIfist[-] 使用 FIST 而不是 ftol()
/hotpatch 确保可热修补映像的函数填充
/arch:<SSE|SSE2> CPU 结构的最低要求,为以下内容之一:
    SSE - 启用支持 SSE 的 CPU 可用的指令
    SSE2 - 启用支持 SSE2 的 CPU 可用的指令

                              -输出文件-

/Fa[file] 命名程序集列表文件            /FA[scu] 配置程序集列表
/Fd[file] 命名 .PDB 文件                /Fe<file> 命名可执行文件
/Fm[file] 命名映射文件                  /Fo<file> 命名对象文件
/Fp<file> 命名预编译头文件              /Fr[file] 命名源浏览器文件
/FR[file] 命名扩展 .SBR 文件
/doc[file] 处理 XML 文档注释,并可选择命名 .xdc 文件

                              -预处理器-

/AI<dir> 添加到程序集搜索路径           /FU<file> 强制使用程序集/模块
/C 不抽出注释                           /D<name>{=|#}<text> 定义宏
/E 将预处理定向到 stdout                /EP 预处理到标准输出,没有 #line
/P 预处理到文件                         /Fx 将插入的代码合并到文件中
/FI<file> 命名强制包含文件              /U<name> 移除预定义的宏
/u 移除所有预定义的宏                   /I<dir> 添加到包含搜索路径
/X 忽略“标准位置”

                                -语言-

/Zi 启用调试信息                        /Z7 启用旧式调试信息
/Zp[n] 在 n 字节边界上包装结构          /Za 禁用扩展
/Ze 启用扩展(默认)                      /Zl 忽略 .OBJ 中的默认库名
/Zg 生成函数原型                        /Zs 只进行语法检查
/vd{0|1|2} 禁用/启用 vtordisp           /vm<x> 指向成员的指针类型
/Zc:arg1[,arg2] C++ 语言一致性,这里的参数可以是:
    forScope[-] - 对范围规则强制使用标准 C++
    wchar_t[-] - wchar_t 是本机类型,不是 typedef
/ZI 启用“编辑并继续”调试信息          /openmp 启用 OpenMP 2.0 语言扩展

                              - 杂项 -

@<file> 选项响应文件                    /?, /help 打印此帮助消息
/bigobj 生成扩展的对象格式              /c 只编译,不链接
/errorReport:option 将内部编译器错误报告给 Microsoft
    none - 不发送报告                       prompt - 提示立即发送报告
    queue - 在下一次管理员登录时,提示发送报告(默认)
    send - 自动发送报告                 /FC 诊断中使用完整路径名
/H<num> 最大外部名称长度                /J 默认 char 类型是 unsigned
/nologo 取消显示版权消息                /showIncludes 显示包含文件名
/Tc<source file> 将文件编译为 .c        /Tp<source file> 将文件编译为 .cpp
/TC 将所有文件编译为 .c                 /TP 将所有文件编译为 .cpp
/V<string> 设置版本字符串               /w 禁用所有警告
/wd<n> 禁用警告 n                       /we<n> 将警告 n 视为错误
/wo<n> 发出一次警告 n                   /w<l><n> 为 n 设置警告等级 1-4
/W<n> 设置警告等级(默认 n=1)            /Wall 启用所有警告
/WL 启用单行诊断                        /WX 将警告视为错误
/Yc[file] 创建 .PCH 文件                /Yd 将调试信息放在每个 .OBJ 中
/Yl[sym] 为调试库插入 .PCH 引用         /Yu[file] 使用 .PCH 文件
/Y- 禁用所有 PCH 选项                   /Zm<n> 最大内存分配(默认为 %)
/Wp64 启用 64 位端口定位警告

                                -链接-

/LD 创建 .DLL                           /LDd 创建 .DLL 调试库
/LN 创建 .netmodule                     /F<num> 设置堆栈大小
/link [链接器选项和库]                  /MD 与 MSVCRT.LIB 链接
/MT 与 LIBCMT.LIB 链接                  /MDd 与 MSVCRTD.LIB 调试库链接
/MTd 与 LIBCMTD.LIB 调试库链接

                         -代码分析-

/analyze[:WX-] 启用代码分析
    WX- - 即使调用了 /WX,也不应将代码分析警告视为错误

XGHeaven 2014-08-13
  • 打赏
  • 举报
回复
引用 10 楼 adlay 的回复:
DEBUG 版为了在变量访问越界的时候做出检测,在变量之间插入了一些填固定值的内容
引用 9 楼 mymtom 的回复:
DEBUG版本有调试信息,RELEASE版本的间隔就是4啦
谢谢,我去网上找了找,说关掉有个叫安全开发生命周期检查就行了,然后再换成release版本就是连续的了,谢谢。
XGHeaven 2014-08-13
  • 打赏
  • 举报
回复
引用 11 楼 zhao4zhong1 的回复:
编译器的命令行选项都有哪些,作用都是什么,这些知识补一补。
这跟命令行有什么关系?
XGHeaven 2014-08-13
  • 打赏
  • 举报
回复
引用 12 楼 litch008 的回复:
因为你是从下往上做减法的,并且没有借位
我是用计算器按出来的……并且是上面那个减去下面那个的,保证是正数……
taodm 2014-08-12
  • 打赏
  • 举报
回复
谁跟你说的栈中变量是连续的?离那货远点。
引用 3 楼 XGHeaven 的回复:
[quote=引用 2 楼 lovesmiles 的回复:] 栈地址就一定是连续的了?你将你这个代码放到g++看看,函数内的变量的栈地址是从高到低还是从低到高各个编译器都不一样,何况是变量之间呢?要要通过地址差求类型长度,就应该用数组,而不是单独的变量
我没说栈的地址是连续的,我的意思是栈中变量是连续的,但变量的长度应该是4,所以应该相差4才对,而不是12[/quote]
XGHeaven 2014-08-12
  • 打赏
  • 举报
回复
引用 1 楼 wanght99 的回复:
可能是编译器优化,16字节对齐,提升内存效率的。你看看地址是不是都是16的倍数
没有,都相差12,也就是12的倍数
XGHeaven 2014-08-12
  • 打赏
  • 举报
回复
引用 2 楼 lovesmiles 的回复:
栈地址就一定是连续的了?你将你这个代码放到g++看看,函数内的变量的栈地址是从高到低还是从低到高各个编译器都不一样,何况是变量之间呢?要要通过地址差求类型长度,就应该用数组,而不是单独的变量
我没说栈的地址是连续的,我的意思是栈中变量是连续的,但变量的长度应该是4,所以应该相差4才对,而不是12
勤奋的小游侠 2014-08-12
  • 打赏
  • 举报
回复
栈地址就一定是连续的了?你将你这个代码放到g++看看,函数内的变量的栈地址是从高到低还是从低到高各个编译器都不一样,何况是变量之间呢?要要通过地址差求类型长度,就应该用数组,而不是单独的变量
wanght99 2014-08-12
  • 打赏
  • 举报
回复
可能是编译器优化,16字节对齐,提升内存效率的。你看看地址是不是都是16的倍数

65,086

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧