数组越界问题——危险

C++中数组越界问题

运行环境

本次程序的运行环境是C-Free 5.0.

今天写程序,想要实现判断一个字符串是否是回文字符串的问题,代码如下:

void Reverse(char *str, int from, int to){
    if(NULL == str)
        return ;

    while(from < to){
        char temp = str[from];
        str[from++] = str[to];
        str[to--] = temp;
    }
}

bool IsPalindrome(char *str){
    char *p = str;
    Reverse(str, 0, strlen(str)-1);

    int begin = 0;
    while(begin < strlen(str)){
        if(p[begin] != str[begin])
            return false;
        ++begin;
    }
    return true;
}

写这个代码的时候出现了问题,那就是无论输入的字符串为何值,结果都为true。这个问题其实是深拷贝与浅拷贝的问题,

char *p = str;

该代码属于浅拷贝,指针p和str都指向同一个地址,因此当翻转str过后,p指向的值也发生变化,和str相同。因此需要执行深拷贝。所以改代码如下:

bool IsPalindrome(char *str){
    char *p = NULL;
    strcpy(p, str);
    cout << p << endl;
    Reverse(str, 0, strlen(str)-1);

    int begin = 0;
    while(begin < strlen(str)){
        if(p[begin] != str[begin])
            return false;
        ++begin;
    }
    return true;
}

结果在运行的时候又出现问题,编译没有出错。这个结果很容易分析,因为strcpy()执行的是深拷贝,因此指针p需要申请空间,而不能为NULL,因此需要修改

char *p = new char[strlen(str)];

修改过后就可以很简单的判断该字符串是否为回文。但是自己想要亲手实现以下一下strcpy的过程,于是有代码:

bool IsPalindrome(char *str){
    char *p = new char[strlen(str)];
    int i=0;
    while(i < strlen(str)){
        p[i] = str[i];
        i++;
    }

    Reverse(str, 0, strlen(str)-1);

    int begin = 0;
    while(begin < strlen(str)){
        if(p[begin] != str[begin])
            return false;
        ++begin;
    }
    return true;
}

这个代码的运行结果很诡异,因为添加了很多莫名其妙的数字,虽然到最后结果是正确的,但是对此我还是很有疑惑。因为我p数组的大小是给定了的,就为strlen(str),但是当打印出p过后发现其大小大于strlen(str),首先就感觉是数组越界了,但是我已经定义了数组的大小,为何在赋值完成过后还会越界呢?经过分析发现是因为我们将数组p赋值过后,没有在最后一步加上结束符’\0’,因此p就会一直往后寻找,直到发现’\0’才视为数组结束。修改代码如下

while(i < strlen(str)){
    p[i] = str[i];
    i++;
}
p[i] = '\0';

解决了该问题,通过该问题我们发现,在使用数组进行深拷贝的时候,我们规定的数组大小似乎是没用的,因为当赋值过后,数组只看结尾的符’\0’,找到结尾符,就表明数组的大小是多少,并且在C++中,也没有给与特定的处理,因此当忘记添加p[i] = '\0';时,就很容易出现一些莫名其妙的错误。因此建议尽量使用函数库提供的函数strcpy()。

我还测试了当使用IO输入时的情况,发现IO输入会在字符结尾自动加上’\0’符号

int size;
cin >> size;
char *p = new char[size];
for(int i=0; i<size+1; i++)
    cin >> p[i];
cout<<p<<endl;
cout<<strlen(p)<<endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值