C字符串数组与字符串指针

1,首先源码:

#include <stdio.h>
#include <unistd.h>

int our_init_data = 30; 
int our_noinit_data;

void our_prints(int a,int b,int c,int d)
{
        int our_local_data = 1;
        char buf[1024];
        char *rodata="hello,world,string"; //字符串指针
        char arr[]="Hello,world,array"; //字符串数组
    
        printf("\nPid of the process is = %d", getpid());
        printf("\nAddresses which fall into:");
        printf("\n 1) Data  segment = %p", &our_init_data);
        printf("\n 2) BSS   segment = %p", &our_noinit_data);
        printf("\n 3) Code  segment = %p", &our_prints);
        printf("\n 4) Stack segment = %p", &our_local_data);
        printf("\n 5) rodata segment = %p", rodata);
        printf("\n 6) arr segment = %p\n", arr);
         printf("%x\n",&arr[0]);

        a=b+c+d;    
        sprintf(buf,"cat /proc/%d/maps",getpid());
        system(buf);
}

int main()
{
        //int n=50,j=500;

        our_prints(100,200,300,400);    
        return 0;
}
~                                     

2,运行结果

 ~                                                                                                                                   
[root@localhost st]# ./a.out       
Pid of the process is = 21611
Addresses which fall into:
 1) Data  segment = 0x8049880
 2) BSS   segment = 0x804988c
 3) Code  segment = 0x8048414
 4) Stack segment = 0xbfc11970
 5) rodata segment = 0x8048670
 6) arr segment = 0xbfc1155e
bfc1155e
00110000-0024f000 r-xp 00000000 fd:00 16090599   /lib/libc-2.5.so
0024f000-00251000 r-xp 0013f000 fd:00 16090599   /lib/libc-2.5.so
00251000-00252000 rwxp 00141000 fd:00 16090599   /lib/libc-2.5.so
00252000-00255000 rwxp 00252000 00:00 0 
00b76000-00b90000 r-xp 00000000 fd:00 16090598   /lib/ld-2.5.so
00b90000-00b91000 r-xp 00019000 fd:00 16090598   /lib/ld-2.5.so
00b91000-00b92000 rwxp 0001a000 fd:00 16090598   /lib/ld-2.5.so
00b9a000-00b9b000 r-xp 00b9a000 00:00 0          [vdso]
08048000-08049000 r-xp 00000000 fd:00 1083484    /var/ftp/pub/st/a.out
08049000-0804a000 rw-p 00000000 fd:00 1083484    /var/ftp/pub/st/a.out
b7fe7000-b7fe9000 rw-p b7fe7000 00:00 0 
b7ff5000-b7ff6000 rw-p b7ff5000 00:00 0 
bfbfe000-bfc13000 rw-p bffea000 00:00 0          [stack]


3, 检查只读数据段objdump -S -j .rodata 

[root@localhost st]# objdump -S -j .rodata
a.out:     file format elf32-i386
Disassembly of section .rodata:

08048664 <_fp_hw>:
 8048664:       03 00 00 00                                         ....


08048668 <_IO_stdin_used>:
 8048668:       01 00 02 00                                         ....


0804866c <__dso_handle>:
 804866c:       00 00 00 00 68 65 6c 6c 6f 2c 77 6f 72 6c 64 2c     ....hello,world,
 804867c:       73 74 72 69 6e 67 00 0a 50 69 64 20 6f 66 20 74     string..Pid of t
 804868c:       68 65 20 70 72 6f 63 65 73 73 20 69 73 20 3d 20     he process is = 
 804869c:       25 64 00 0a 41 64 64 72 65 73 73 65 73 20 77 68     %d..Addresses wh
 80486ac:       69 63 68 20 66 61 6c 6c 20 69 6e 74 6f 3a 00 0a     ich fall into:..
 80486bc:       20 31 29 20 44 61 74 61 20 20 73 65 67 6d 65 6e      1) Data  segmen
 80486cc:       74 20 3d 20 25 70 00 0a 20 32 29 20 42 53 53 20     t = %p.. 2) BSS 
 80486dc:       20 20 73 65 67 6d 65 6e 74 20 3d 20 25 70 00 0a       segment = %p..
 80486ec:       20 33 29 20 43 6f 64 65 20 20 73 65 67 6d 65 6e      3) Code  segmen
 80486fc:       74 20 3d 20 25 70 00 0a 20 34 29 20 53 74 61 63     t = %p.. 4) Stac
 804870c:       6b 20 73 65 67 6d 65 6e 74 20 3d 20 25 70 00 0a     k segment = %p..
 804871c:       20 35 29 20 72 6f 64 61 74 61 20 73 65 67 6d 65      5) rodata segme
 804872c:       6e 74 20 3d 20 25 70 00 0a 20 36 29 20 61 72 72     nt = %p.. 6) arr
 804873c:       20 73 65 67 6d 65 6e 74 20 3d 20 25 70 0a 00 25      segment = %p..%
 804874c:       78 0a 00 63 61 74 20 2f 70 72 6f 63 2f 25 64 2f     x..cat /proc/%d/
 804875c:       6d 61 70 73 00 48 65 6c 6c 6f 2c 77 6f 72 6c 64     maps.Hello,world
 804876c:       2c 61 72 72 61 79 00                                ,array.

    可见字符串指针和字符串数组都在 只读数据段

4,检查代码段objdump -S -j .text

        char *rodata="hello,world,string";
 8048424:       c7 45 fc 70 86 04 08    movl   $0x8048670,0xfffffffc(%ebp) ;立即数
        char arr[]="Hello,world,array";
 804842b:       a1 61 87 04 08          mov    0x8048761,%eax              ;直接引用地址
 8048430:       89 85 e6 fb ff ff       mov    %eax,0xfffffbe6(%ebp)
 8048436:       a1 65 87 04 08          mov    0x8048765,%eax
 804843b:       89 85 ea fb ff ff       mov    %eax,0xfffffbea(%ebp)
 8048441:       a1 69 87 04 08          mov    0x8048769,%eax
 8048446:       89 85 ee fb ff ff       mov    %eax,0xfffffbee(%ebp)
 804844c:       a1 6d 87 04 08          mov    0x804876d,%eax
 8048451:       89 85 f2 fb ff ff       mov    %eax,0xfffffbf2(%ebp)
 8048457:       0f b7 05 71 87 04 08    movzwl 0x8048771,%eax
 804845e:       66 89 85 f6 fb ff ff    mov    %ax,0xfffffbf6(%ebp)

字符串常量 只读数据段的地址 直接被直接付给了变量;但是 字符串数组 只读数据段的地址所指向的内容被付给了变量

5,总结

   字符串指针 和  字符串数组 在编译的时候都存储在 只读数据段.rodata section。但是在赋值的时候,字符串指针获得的是 只读数据段的地址,而字符串数组 获得的是 堆栈段的地址。因此字符串指针 是不能修改的,但是 字符串数组 是可以修改的

posted on 2012-05-04 12:05  Tonystz  阅读(193)  评论(0编辑  收藏  举报