上网查一下数组越界,这是一个很常见的错误,是初学者常犯的错误。这里记录一下我在上面所犯的错误。
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) |