1 #include "string.h" 2 #include "stdio.h" 3 void main(){ 4 struct test 5 { 6 char a[10];//length: 10 7 char b[20];//length: 20 8 }; 9 struct test t1,t2; 10 int i ; 11 12 memcpy( t1.a ,"1234567890" ,10); 13 memcpy( t1.b ,"abcdefghijklmnopqrst",20); 14 15 memset( &t2 , NULL , sizeof(t2) ); 16 printf( "=========before set value to t2=========\n" ); 17 18 printf("t2.a:%.*s\nt2.b:%.*s \n",10,t2.a,20,t2.b); 19 /************************************************************************/ 20 /* t2.a的长度为10,给t2.a赋值时,循环长度30 超出定义 21 /************************************************************************/ 22 for( i=0; i<30; i++ ){ //这里的30是非法的,在编译时不会报错 23 t2.a[i] = t1.a[i]; //这里只是想改变了a的值 24 } 25 26 printf("=========after set value to t2=========\n"); 27 28 printf("t2.a:%.*s\nt2.b:%.*s \n",10,t2.a,20,t2.b); //结果t2.b的值也被改变了 29 }
执行结果:
=========before set value to t2=========
t2.a:
t2.b:
=========after set value to t2=========
t2.a:1234567890
t2.b:abcdefghijklmnopqrst
程序只是想改变t2.a的值,但是ta.b的值也被更改了。
上面的代码是常见的内存错误:操作越过了内存的边界.
使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。
以上第22行,程序员写程序时应清醒的知道 正在操作的数组的长度,不可轻易越界。
正确应该为
//方法1,确定终止条件,取最小值 for( i=0; i<(30>10?10:30); i++ ){ t2.a[i] = t1.a[i]; //这里只是想改变了a的值 }
//方法2:在循环内加入终止条件 for( i=0; i<30; i++ ){ if(i>=10){ break; } t2.a[i] = t1.a[i]; //这里只是想改变了a的值 }
正确的运行结果 :
=========before set value to t2=========
t2.a:
t2.b:
=========after set value to t2=========
t2.a:1234567890
t2.b:
这里的t2.a,t2.b 两个内存地址是相邻排布的。相对来说影响不是很大 ,也容易看出错误。
最糟糕的的情况:在几千行C源码中, 出现的操作越界问题,那结果是不可预知的(这种程式在编译时不会报错)。
慎用