从一个例子看C++中的内存——我也是无聊才写这玩意儿
故事的起因是这样的
跟Lz争着争着就觉得,“非要跟他战个痛快!”于是就写了本文。。。
好吧,是因为我论文编不下去才写的
先看代码
# include <iostream>
using namespace std;
int main(void)
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
char a[100];
cout<<"请输入一个点分十进制IP地址:"<<endl;
cin.getline(a,99);
int sum=0,i=0;
while(*(a+i)!='.')
{
int n=*(a+i)-'0';
sum*=10;
sum+=n;
i++;
}
int j=7;
char b[8]={'0','0','0','0','0','0','0','0'};
cout<<b<<endl;
while(sum>=1)
{
int p=sum%2;
sum=sum/2;
char r=p+'0';
b[j]=r;
j--;
}
cout<<b<<endl;
return 0;
}
我删除了最后一部分,因为它与我们的问题无关。增加了两行:
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
用途是使用现场的文件内容作为标准输入输出,这样就不用每次去敲char a[]
了。本例中我使用的输入是"11.11.11.11"。
编译环境
Visual Studio 2010 (人艰不拆,恳请不要问我是否正版)
Windows 7
这样的环境确定了一点,程序中一般变量在栈空间是由3大向小生长的,变量自身是小端模式,但一个数组下标小者,地址值也小。
下面这个更重要一点:原文
在Debug 模式下:
VC 会把未初始化的栈内存全部填成0xcc,当字符串看就是 烫烫烫烫……
会把未初始化的堆内存全部填成0xcd,当字符串看就是 屯屯屯屯……
目的是可以让我们方便地看出那些内存没初始化。
但是Release 模式下不会有这种附加动作,原来那块内存里是什么就是什么。
我就在Debug模式下做一次演示,大家有兴趣可以试试Release下的情况。
要上图了,请注意观察:
第一次cout<<b<<endl前的截图
图可能有点大……
蓝色箭头划过的部分是 char b[]
的内存空间, 红色箭头划过的 char a[]
的内存空间。中间其他的变量:sum、i、j等等。主要变量p此时还有初始化,但是它跟我们的问题无关。真正需要注意的就是 b 和 j
&b = 0x004ff730
&j = 0x004ff740 //j在b的空间的后面
特别是j变量因为比较小(==7),所以在内存里是 07 00 00 00
第二次cout<<b<<endl前的截图
看到了么,“不是风动也不是旗动,也而不是心动”,而是变量j
动了。所以最后输出的b也会不同。
因为b被“stack overflow”了,控制b如何结束的工作非常危险的交给了后面的变量,还好这里的j小,要是 j=-1
,就只能靠 i
了……
总结
这个问题里面真正有意思的似乎还不是b输出的变化,而是为什么只有8个字符长的b变量,跟它前面紧挨的j变量相差了16个距离。
事实上所有的连续变量之间都空开了8个字节(用0xCC填充)
是为了对齐么?求指教~
最后,不知道happy同学满意了否,满意请点赞 :D
posted on 2014-05-04 16:53 Robert Liu 阅读(174) 评论(0) 编辑 收藏 举报