• 从一个例子看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 b[] 的内存空间, 红色箭头划过的 char a[] 的内存空间。中间其他的变量:sum、i、j等等。主要变量p此时还有初始化,但是它跟我们的问题无关。真正需要注意的就是 b 和 j

    &b = 0x004ff730
    &j = 0x004ff740 //j在b的空间的后面
    

    特别是j变量因为比较小(==7),所以在内存里是 07 00 00 00

    第二次cout<<b<<endl前的截图

    第二次cout

    看到了么,“不是风动也不是旗动,也而不是心动”,而是变量j动了。所以最后输出的b也会不同。

    因为b被“stack overflow”了,控制b如何结束的工作非常危险的交给了后面的变量,还好这里的j小,要是 j=-1 ,就只能靠 i 了……

    总结

    这个问题里面真正有意思的似乎还不是b输出的变化,而是为什么只有8个字符长的b变量,跟它前面紧挨的j变量相差了16个距离。

    事实上所有的连续变量之间都空开了8个字节(用0xCC填充)

    是为了对齐么?求指教~

    最后,不知道happy同学满意了否,满意请点赞 :D

  • 相关阅读:
    指针与数组实例练习(指针运算)
    C语言数组和函数实例练习(二)
    C语言数组和函数实例练习(一)
    近一个月的学习总结(4.8—5.12)
    Java网页小程序——Java Applet
    数据结构(二)线性表——链表
    JDBC的使用(MySQL数据库)
    Python变量类型及变量
    Shell编程语法
    文本处理三剑客
  • 原文地址:https://www.cnblogs.com/liuameng/p/3707415.html
Copyright © 2020-2023  润新知