qey

Atitude is Everything.-- 关注C/C++,关注Linux(Unix) ,关注网络。 Better Late Than Never.
随笔 - 4, 文章 - 13, 评论 - 7, 引用 - 0
数据加载中……

内存覆盖问题

 内存覆盖问题
   
    关于静态数据区的数据修改以及覆盖,在debug 模式不能通过的,在release 模式正常运行。

    cin>>i;    
    
char* str1="56789";
    
char* str2="123456789";    
    strcpy(str1,str2);
    cin
>>i;    
    cout
<<str1<<endl;
    cout
<<str2<<endl;

0040108E   call        
00401770                    //cin Call
00401093   mov         edi,4190F4h            //str1开始地址
00401098   or          ecx,0FFh
0040109B   xor         eax,eax
0040109D   repne scas  
byte ptr [edi]
0040109F   not         ecx
004010A1   sub         edi,ecx                    
//结果是edi回到4190F4h
004010A3   lea         eax,[esp+0Ch]
004010A7   mov         edx,ecx
004010A9   mov         esi,edi
004010AB   mov         edi,4190ECh
004010B0   push        eax
004010B1   shr         ecx,
2
004010B4   rep movs    dword ptr [edi],dword ptr [esi]        
//操作后结果为:内存变化[1]
004010B6   mov         ecx,edx
004010B8   and         ecx,
3
004010BB   rep movs    
byte ptr [edi],byte ptr [esi]            //操作后结果为:内存变化[2]
004010BD   mov         ecx,41B058h
004010C2   call        
00401770                    //cin Call
004010C7   push        4190ECh
004010CC   push        41AFC8h
004010D1   call        00401F90
004010D6   add         esp,
8
004010D9   mov         esi,eax
004010DB   mov         ecx,esi
004010DD   push        0Ah
004010DF   call        
00401600
004010E4   mov         ecx,dword ptr [esi]
004010E6   mov         bl,
6
004010E8   xor         edi,edi
004010EA   mov         edx,dword ptr [ecx
+4]
004010ED   mov         cl,
byte ptr [edx+esi+4]
004010F1   test        bl,cl
004010F3   lea         eax,[edx
+esi]




004190EC  
35 36 37 38  5678        //str1
004190F0  39 00 00 00  9
004190F4  
31 32 33 34  1234        //str2
004190F8  35 36 37 38  5678
004190FC  
39 00 00 00  9

//内存变化[1]*****************************

004190EC  
31 32 33 34  1234
004190F0  
35 36 37 38  5678
004190F4  
31 32 33 34  1234
004190F8  
35 36 37 38  5678
004190FC  
39 00 00 00  9

//内存变化[2]*****************************
004190EC  31 32 33 34  1234
004190F0  
35 36 37 38  5678
004190F4  
39 00 33 34  9.34
004190F8  
35 36 37 38  5678
004190FC  
39 00 00 00  9

输出结果为:
123456789
9
据说是华为的笔试题目!

 char* str1="56789";
 char* str2="123456789"; 

 char* str2="123456789"; 
 char* str1="56789";
在静态数据区分配内存,都是"56789"位于"123456789"前面,据说是编译器对静态数据区内存做了优化。

posted on 2008-11-11 18:26 无声无色 阅读(917) 评论(3)  编辑 收藏 引用 所属分类: 面试集合

评论

# re: 内存覆盖问题  回复  更多评论   

【编译器为:VC 6.0】
有人说编译优化了,也许吧,可是多加一些数据的时候,就感觉排序有点混乱了!!
char* str1="56789";
char* str2="123456789";
char* str2="1234";

在静态数据区 内存中分配就如下:
00471084 31 32 33 34 1234
00471088 00 00 00 00 ....
0047108C 35 36 37 38 5678
00471090 39 00 00 00 9...
00471094 31 32 33 34 1234
00471098 35 36 37 38 5678
0047109C 39 00 00 00 9...

再加多一些呢??
char* str2="123456789";
char* str1="56789";
char *str3 = "1234";
char *str4 = "123";
char *str5 = "12";
char *str6 = "123456";
char *str7 = "12345678901";
在静态数据区 内存中分配就变成如下:
00471064 31 32 33 34 1234
00471068 35 36 37 38 5678
0047106C 39 30 31 00 901.
00471070 00 00 00 00 ....
00471074 31 32 33 34 1234
00471078 35 36 00 00 56..
0047107C 31 32 00 00 12..
00471080 31 32 33 00 123.
00471084 31 32 33 34 1234
00471088 00 00 00 00 ....
0047108C 35 36 37 38 5678
00471090 39 00 00 00 9...
00471094 31 32 33 34 1234
00471098 35 36 37 38 5678
0047109C 39 00 00 00 9...
2008-11-11 18:50 | 无声无色

# re: 内存覆盖问题  回复  更多评论   

另外需要说明的是:这个例子中的str1 和str2 都是指向静态数据区的字符串的;在bebug 模式下,运行会出错;如果是release 模式,就可以通过,而产生内存覆盖。

首相看一下release 模式下,栈区数据;
如果定义的数据是在栈区会是什么效果呢?
char bb[]="123456789";
char aa[]="56789";
strcpy(bb,aa);
cout<<aa<<endl;
cout<<bb<<endl;
结果
123456789
9
char aa[]="56789";
char bb[]="123456789";
strcpy(bb,aa);
cout<<aa<<endl;
cout<<bb<<endl;
结果
123456789
9
应该是在release 模式下做了优化,编译器先分配aa,后在分配bb 的空间的缘故!

而在debug 模式下,并没有优化,而是按照声明的先后顺序来安排栈空间;
所以在debug 模式下的输出有点不同;
char aa[]="56789";
char bb[]="123456789";
strcpy(bb,aa);
cout<<aa<<endl;
cout<<bb<<endl;
结果
123456789
123456789
冲毁了一个栈区的dword,只是侥幸那里没有数据而没有出错!

2008-11-11 19:43 | 无声无色

# re: 内存覆盖问题  回复  更多评论   

release 模式下是可以有 静态常量数据区 的数据的修改操作的!
debug 模式是不允许的,会提示内存非法操作错误错误!
2008-11-11 19:59 | 无声无色

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理