Chinaunix首页 | 论坛 | 博客
  • 博客访问: 453583
  • 博文数量: 72
  • 博客积分: 3186
  • 博客等级: 中校
  • 技术积分: 1039
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-07 16:53
文章分类

全部博文(72)

文章存档

2012年(1)

2011年(5)

2010年(10)

2009年(56)

我的朋友

分类: C/C++

2009-08-05 17:19:10

上网查一下数组越界,这是一个很常见的错误,是初学者常犯的错误。这里记录一下我在上面所犯的错误。

1
比如
int a[10];
这样就定义了a有10个元素,其下标为0~9,这样的话,如果对a[10]操作,就会出现数组越界。让我们来写一段测试代码看看效果。

#include <stdio.h>

void main(void)
{
    int a[10] = {0};
    int i = 0;

    a[10] = 1;
    printf("%d\n", i);
}

这段代码在gcc下可以通过编译,也就是说gcc并不对数组的越界访问做检查。其实这也很好理解,因为在对数组访问的时候,实际上是通过指针来访问的,访问a[10]实际上就是*(a+10),在指针这一层上来说,不存在越界这一说。

上面这段代码执行结果为 1

这说明越界访问,会覆盖掉变量i。。这里涉及到局部变量在运行时的分配,即栈,这个不太懂,暂不讨论。


2  另一种越界的情况
char *strcpy(char *dest, const char *src);
这个函数是复制字符串时用的。将src字符串复制到dest所指地址。
注意:如果参数dest所指的内存空间不够大,可能会造成缓冲区溢出


int sprintf(char *str, const char *format, ...)
根据format字符串来转换并格式化数据,然后将结果复制到参数str所指的字符串数组,直到出现字符串结束符\0为止
注意:如果str分配的大小不够的话,会造成堆栈溢出。。。

#include <stdio.h>
#include <string.h>

void main(void)
{    
    char buf[10];
    char i = 'a';

    sprintf(buf, "abcdefghijklmn");
    printf(buf);
    printf("\n%c\n", i);
}

执行结果:

abcdefghijklmn
k

可见其中数组访问越界就会出了问题,将下面的数据i给覆盖掉了。。。
要注意的是,sprintf是造成栈溢出,这跟局部变量一样,而strcpy是造成缓冲区溢出。这里是有区别的,我还不太理解,先不讨论。

上面的两个函数都可以使用其的另一种形式,即strncpy  和 snprintf,这样可以指定操作的字节数。我们在使用时指明要复制或格式化的字符串的长度,这样就会少犯错误。


这次我犯的错误就是在这里出了问题,sprintf的时候没有注意,分配的数组不够大,造成越界访问,改变了其他局部变量的值。。出现的结果是程序出错很其怪,调试的时候打印出的数据很随机。最后搞了两天。


阅读(6263) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~