【转载】关于char * c="hello"与char c[]="hello"的区别

 前两天在VC群里,看一初学者在群里问char * c="hello"与char c[]="hello"的区别。结果群里冒出了无数种最这两种定义字符串方式的不同说法。结果无数开发多年C++的人也说不清楚。
      我现在来分析下他们直接真的区别。现在我打开VC写一短很小的代码,然后我们来反汇编。看真的区别。

#include  < stdio.h >
void  main()
{
    
char   *  c  =   " hello " ;
    printf(
" %s/n " ,c);
}
反汇编结果如下
00401010     push         ebp
00401011     mov          ebp,esp
00401013     sub          esp,44h
00401016     push         ebx
00401017     push         esi
00401018     push         edi
00401019     lea          edi,[ebp-44h]
0040101C     mov          ecx,11h
00401021     mov          eax,0CCCCCCCCh  ;这里之前是VC debug特有的,主要是为了调试创建44h个自己内存,全部初始化CC 也就是int3 调试器用的。
00401026     rep  stos    dword ptr [edi]
4 :        char * c =  " hello " ;
00401028     mov          dword ptr [ebp- 4 ],offset string  " hello "  ( 00422020 ; 把字符串的地址放进了第一个局部变量,c是变量分配在堆栈中也就是doord prt[bp-4]
5 :        printf( " %s/n " ,c) ;
0040102F     mov          eax,dword ptr [ebp- 4 ]
00401032     push         eax
00401033     push         offset string  " %s/n "  ( 0042201c )
00401038     call         printf ( 00401070 )
0040103D     add          esp, 8
总结下:char * c = "hello"; c是个分配在堆栈中的一个变量。里面装的是字符串hello的首地址,而hello是常量区。PE文件在编译的时候就确定了的。

下面再来看char c[]="hello";
#include  < stdio.h >
void  main()
{
    
char  c[]  =   " hello " ;
    printf(
" %s/n " ,c);
}
反汇编:
00401019     lea          edi,[ebp-48h]
0040101C     mov          ecx,12h
00401021     mov          eax,0CCCCCCCCh
00401026     rep  stos    dword ptr [edi];前面是调试用的不管
4 :        char c[] =  " hello " ;
00401028     mov          eax,[string  " hello "  ( 00422020 )]
0040102D     mov          dword ptr [ebp- 8 ],eax;把hello的前4个字符放入[ebp- 8 ]的堆栈内存中
00401030     mov          cx,word ptr [string  " hello " + 4  ( 00422024 )]
00401037     mov          word ptr [ebp- 4 ],cx ; 把hello的第5个字符放入[ebp-4]高地址中
5 :        printf( " %s/n " ,c) ;
0040103B     lea          edx,[ebp- 8 ]
0040103E     push         edx
0040103F     push         offset string  " %c/n "  ( 0042201c )
00401044     call         printf ( 00401070 )
00401049     add          esp, 8

上面我只是用"hello"做例子,如果是helloworld放入char c[]呢,那会是这样的。
dword ptr[ebp-c]="hell"  dword ptr[ebp-8]="owor" word ptr[ebp-4]="ld"这样放。
总结下:
也就是说char []c = "hello";
"hello"是放在堆栈中保存的,跟上面的那个例子不同,由于hello是堆栈中的所以是可以修改的。而常量区里的是不可以修改的。因为PE的内存页属性是只读的。当然可以有办法强行修改它。那属于HACK技术了。
那c保存在哪里呢?c根本在内存中不存在,只是编译器的一个标记,用于编译期来计算地址用的。用完就不要了。    
                                                                                          作者:朱剑            

文章来自:http://www.cnblogs.com/zhujian198/archive/2008/05/06/1185389.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值