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源码中, 出现的操作越界问题,那结果是不可预知的(这种程式在编译时不会报错)。

慎用

posted on 2013-11-11 14:28  遥远的绝响  阅读(854)  评论(0编辑  收藏  举报