字符串变量存储位置

参考:

https://blog.csdn.net/bxw1992/article/details/74011951

https://blog.csdn.net/daiyutage/article/details/8605580?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-3&spm=1001.2101.3001.4242

 

代码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   lh03061238  阅读(436)  评论(0编辑  收藏  举报

编辑推荐:
· 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)

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示