字符串变量存储位置
参考:
https://blog.csdn.net/bxw1992/article/details/74011951
代码1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> #include <stdlib.h> int test() { g_name[0]= '1' ; //a[0]=1 g_name[1]= '0' ; //a[1]=2 g_name[2]= '1' ; //a[2]=3 g_name[3]= '\0' ; //a[2]=3 printf ( "define_print() : %s\n" , g_name); } int main() { test(); return 0; } |
运行结果;
define_print() : 101
反汇编如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 080483c4 <test>: #include <stdio.h> #include <stdlib.h> int test() { 80483c4: 55 push %ebp 80483c5: 89 e5 mov %esp,%ebp 80483c7: 83 ec 28 sub $0x28,%esp char g_name[]= "123" ; 80483ca: a1 e5 84 04 08 mov 0x80484e5,%eax 80483cf: 89 45 f4 mov %eax,-0xc(%ebp) g_name[0]= '1' ; //a[0]=1 80483d2: c6 45 f4 31 movb $0x31,-0xc(%ebp) g_name[1]= '0' ; //a[1]=2 80483d6: c6 45 f5 30 movb $0x30,-0xb(%ebp) g_name[2]= '1' ; //a[2]=3 80483da: c6 45 f6 31 movb $0x31,-0xa(%ebp) g_name[3]= '\0' ; //a[2]=3 80483de: c6 45 f7 00 movb $0x0,-0x9(%ebp) //p[0]='1'; //a[0]=1 //p[1]='2'; //a[1]=2 //p[2]='3'; //a[2]=3 printf ( "define_print() : %s\n" , g_name); 80483e2: b8 d0 84 04 08 mov $0x80484d0,%eax 80483e7: 8d 55 f4 lea -0xc(%ebp),%edx 80483ea: 89 54 24 04 mov %edx,0x4(%esp) 80483ee: 89 04 24 mov %eax,(%esp) 80483f1: e8 fe fe ff ff call 80482f4 < printf @plt> } 80483f6: c9 leave 80483f7: c3 ret 080483f8 <main>: int main() { 80483f8: 55 push %ebp 80483f9: 89 e5 mov %esp,%ebp 80483fb: 83 e4 f0 and $0xfffffff0,%esp test(); 80483fe: e8 c1 ff ff ff call 80483c4 <test> return 0; 8048403: b8 00 00 00 00 mov $0x0,%eax } |
可以看出,
1 | char g_name[]= "123" ; |
1 2 | 80483ca: a1 e5 84 04 08 mov 0x80484e5,%eax 80483cf: 89 45 f4 mov %eax,-0xc(%ebp) |
是把字符串字面量在全局常量区的内容复制到栈中的字符数组。字符串字面量的地址是0x80484e5,字符数组的地址是-0xc(%ebp),在栈中。
代码2,仅仅将代码1中的
1 | char g_name[]= "123" 改为 |
1 | char *g_name= "123" ;<br><br>运行后发生段错误,<br><br>反汇编得到 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | int test() { 80483c4: 55 push %ebp 80483c5: 89 e5 mov %esp,%ebp 80483c7: 83 ec 28 sub $0x28,%esp char *g_name= "123" ; 80483ca: c7 45 f4 e0 84 04 08 movl $0x80484e0,-0xc(%ebp) g_name[0]= '1' ; //a[0]=1 80483d1: 8b 45 f4 mov -0xc(%ebp),%eax 80483d4: c6 00 31 movb $0x31,(%eax) g_name[1]= '0' ; //a[1]=2 80483d7: 8b 45 f4 mov -0xc(%ebp),%eax 80483da: 83 c0 01 add $0x1,%eax 80483dd: c6 00 30 movb $0x30,(%eax) g_name[2]= '1' ; //a[2]=3 80483e0: 8b 45 f4 mov -0xc(%ebp),%eax 80483e3: 83 c0 02 add $0x2,%eax 80483e6: c6 00 31 movb $0x31,(%eax) g_name[3]= '\0' ; //a[2]=3 80483e9: 8b 45 f4 mov -0xc(%ebp),%eax 80483ec: 83 c0 03 add $0x3,%eax 80483ef: c6 00 00 movb $0x0,(%eax) //p[0]='1'; //a[0]=1 //p[1]='2'; //a[1]=2 //p[2]='3'; //a[2]=3 printf ( "define_print() : %s\n" , g_name); 80483f2: b8 e4 84 04 08 mov $0x80484e4,%eax 80483f7: 8b 55 f4 mov -0xc(%ebp),%edx 80483fa: 89 54 24 04 mov %edx,0x4(%esp) 80483fe: 89 04 24 mov %eax,(%esp) 8048401: e8 ee fe ff ff call 80482f4 < printf @plt> } 8048406: c9 leave 8048407: c3 ret 08048408 <main>: int main() { 8048408: 55 push %ebp 8048409: 89 e5 mov %esp,%ebp 804840b: 83 e4 f0 and $0xfffffff0,%esp test(); 804840e: e8 b1 ff ff ff call 80483c4 <test> return 0; 8048413: b8 00 00 00 00 mov $0x0,%eax } |
可以看出
1 2 | char *g_name= "123" ; 80483ca: c7 45 f4 e0 84 04 08 movl $0x80484e0,-0xc(%ebp)<br><br> 是将字符串字面量的地址赋值给了栈中的指针变量g_name;后面通过指针变量g_name访问时,由于修改全局常量区的数据,所以发生段错误。<br><br><br>结论: |
注意:
指针方式创建的字符数组,是常量字符串,指针指向的内容是没法更改的;方括号([])方式创建的字符数组仅仅是变量,内容可以更改。
1 |
posted on 2020-08-06 13:49 lh03061238 阅读(436) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)