发布日期:2016-02-29 09:24 来源: 标签: 编程语言 C++开发语言 C++字符数组 C++数组越界
本章我们主要学习C++中字符数组越界的问题,下面我们就做一下具体讲解,希望大家多多支持中国站长网络学院。
在写程序的时候,经常会有“CEmployee类继承自CPerson类”这种存在继承关系的两个实体类,在这种案例里通常会有这样一个细节问题:
A:m_szDepartment=new char[strlen(department)+1];为何需要+1呢?在测试里去掉+1后和这个效果一样啊?
B:要给'\0'占个座。是用别人的地盘(越界的部分)保存了自己的信息了吧,不定哪次人家要用,运行结果就不一样了。这恰是最危险的问题。
A:可是在定义字符数组时,比如a[4]时,可以输入5个字符,那么这个数组的'\0'的位置是不是也占用了别人的?
下面就是对上面问题的解答。我们用一个小程序来讲解:
如:
    #include <iostream>   
    using namespace std;  
    int main()   
    {   
        char a[4];  
        cin>>a;  
        cout<<a<<endl;  
        return 0;   
    } 
为了更好的理解最好打开自己熟悉的编程环境,边读边运行你会有以下发现:
输入abcd然后回车,输出是abcd。cout<<a是将字符数组当字符串输出的,显然abcd已经占满了自己的地盘a[0]到a[3],能够“如愿”输出,实际上已经侵占了不该占的内存a[4]单元。当然,恰好a[4]处给脸,就是'\0'。如果”烫烫烫烫烫烫“不必意外。
再运行,输入abcde。我运行的结果是,在VC++6.0中,输出abcde,并弹出了我们熟悉的内存越界错误提示。在codeBlocks下,输出abcde,什么也没提示。这个bug异常凶险啊!
再看下一个程序:
    #include <iostream>   
    using namespace std;  
    int main()   
    {   
        char a[4],b[4];  
        cin>>a;  
        cin>>b;  
        cout<<a<<endl;  
        cout<<b<<endl;  
        return 0;   
    }  
读者自行运行查看结果。观察输入3个字符、4个字符、5个字符的情形,也可以在多个平台上试试,针对结果想想为什么。用单步执行的手段跟踪一下内存中的数据存储,是个强烈建议的办法。
下面是为a和b数组输入3个字符后(分别是abc和hij),利用单步执行看到的结果:

下面是为a和b数组输入5个字符后(分别是abcef和hijkl),利用单步执行看到的结果:

从中看出,VC++6.0中,先定义的a数组的地址大于后定义的数组b的地址,本来为a中输入了abcde,侵占了别人的地盘,随后为b输入hijkl,侵占的就是a的地盘,b[4]即a[0]为l,b[5]即a[1],存储的是'\0'!
下图是在codeBlocks下,用同样的输入调试截出的结果,结果一样:

接下来,再给一个程序,其实就是将输入a和b的顺序换了一下:
#include <iostream>   
using namespace std;  
int main()   
{   
    char a[4],b[4];  
    cin>>b;  
    cin>>a;  
    cout<<a<<endl;  
    cout<<b<<endl;  
    return 0;   

大家可以自行运行程序查看结果。

相关评论

专题信息
    Visual C++是一个功能强大的可视化软件开发工具,是高等院校计算机及相关专业主要核心课程。 本教程对Visual C++ 的应用与开发进行了详细系统的介绍,内容主要包括:Visual C++程序的建立,菜单、工具栏和状态栏的创建,对话框和常用控件,窗口、文档与视图,图形绘制,数据库应用,多媒体技术等。 本教程以案例教学为主,各章节都附有大量的实例,并且操作步骤详细,有利于引导读者更好的消化、理解和实际应用本章节所学的知识内容,希望大家能多多支持中国站长网络学院!