C语言字符串数组与字符串指针详解
来源:互联网 发布:预产期的算法 编辑:程序博客网 时间:2024/06/11 04:40
字符串数组与字符串指针在使用上有很多相似的地方,导致对两者的理解容易混淆.下面我们将从汇编的角度来详细审视一下两者的区别.
先看下面一段代码:
/*file name: test.c*/#include<stdio.h>char *globle_pointer="aaaaaaaaa";char globle_buf[]="bbbbbbbb";void main(){ char *local_pointer="cccccccc"; char local_buf[]="dddddddddd"; *(globle_pointer+2)='A'; globle_buf[2]='B'; *(local_pointer+2)='C'; local_buf[2]='D'; printf("globle_pointer:%s\n",globle_pointer); printf("globle_buf:%s\n",globle_buf); printf("local_pointer:%s\n",local_pointer); printf("local_buf:%s\n",local_buf);}
这个程序可以通过编译,但是一旦运行就会报出”段错误 (核心已转储)”.原因在于第8和第10行.紧跟在字符串指针后的字符串是只读数据,不允许修改.所以第8行和第10行企图修改只读数据段的操作当然受到禁止了.我们可以在汇编代码(片段)中清楚看到这一点:
.file "test.c" .globl globle_pointer .section .rodata.LC0: .string "aaaaaaaaa" .data .align 4 .type globle_pointer, @object .size globle_pointer, 4globle_pointer: .long .LC0 .globl globle_buf .align 4 .type globle_buf, @object .size globle_buf, 9globle_buf: .string "bbbbbbbb" .section .rodata.LC1: .string "cccccccc".LC2: .string "globle_pointer:%s\n".LC3: .string "globle_buf:%s\n".LC4: .string "local_pointer:%s\n".LC5: .string "local_buf:%s\n" .text .globl main .type main, @functionmain:
由于.section .rodata的修饰,.string “aaaaaaaaa”和.string “cccccccc”变成只读数据段,而.string “bbbbbbbb” 和globle_pointer 受到.data修饰,恢复为可读写属性.所以globle_pointer作为全局变量可以修改它的值.这解释了字符串”aaaaaa”,”bbbbbbb”和”ccccccc”的读写性质,等等,”dddddd”在哪儿呢?通过读后续代码,我们可以看到”ddddd”是被代码写入了main函数的栈空间中,而栈是可读写的,所以这也解释了local_buf的读写属性:
movl %esp, %ebp pushl %ecx .cfi_escape 0xf,0x3,0x75,0x7c,0x6 subl $36, %esp movl %gs:20, %eax movl %eax, -12(%ebp) xorl %eax, %eax movl $.LC1, -28(%ebp) movl $1684300900, -23(%ebp) movl $1684300900, -19(%ebp) movw $25700, -15(%ebp)
一共10个’d’,正好在最后三行汇编代码中得到体现.说了这么多,可以看到所谓读写属性本质是由编译器的.section .rodata控制的.为了证明这一点,我们可以尝试突破这个限制:
我们在终端依次输入下面的命令:
$gcc -m32 -c test.c$objcopy --rename-section .rodata=.data test.o out.o$gcc -m32 out.o -o out$./out
我们逐行解释:第一行将test.c编译成test.o,不进行链接.第二行将test.o的只读数据段修改成读写数据段,输出为out.o,第三行链接out.o为可执行程序out,第四行执行这个文件.这时程序可以正常运行:
综上,程序示例中的字符串指针后的字符串是只读的,而字符串数组后的字符串是可读写的.
- C语言字符串数组与字符串指针详解
- C语言字符串、数组与指针结合
- C语言字符串指针---与数组0811
- C语言中,指针字符串与数组字符串的区别
- C语言 字符串指针与二维字符串数组
- C语言:字符串与指针
- c语言字符串与指针
- C字符串数组与字符串指针
- c语言:字符串与字符串指针变量
- C语言字符串指针变量与字符数组的区别
- C语言字符串指针变量与字符数组的区别
- IOS开发---C语言-⑫指针与数组、字符串
- C语言编程基础-13字符串操作与指针数组
- C 语言中指针、字符串与数组的一些关系
- C语言字符串指针与字符数组的区别
- c语言字符串与数组还有指针的总结(1)
- C语言--数组与字符串
- c语言数组与字符串
- ? extends T 与 ? super T
- 免费ARP简单介绍和程序编写
- 将 UIImage 保存到磁盘,用什么方式最好?
- JS this
- 穿越雷区第六届蓝桥杯大赛个人赛决赛(C语言A组)第四题
- C语言字符串数组与字符串指针详解
- iOS添加framework, 报错“dyld: Library not loaded”
- 第十三周-阅读程序
- O2nails美甲机
- note:cloneContents、extractContents、cloneRange()
- Python class method
- 微商创业之微聚元篇
- apache kafka技术分享系列(目录索引)
- Android对图片进行压缩