字符串变量存储位置

参考:

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:

#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]='';  //a[2]=3


printf("define_print() : %s
", g_name);
}
int main()
{
test();
return 0;
}

 

 

运行结果;

define_print() : 101

反汇编如下:

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]='';  //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
", 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
}

 可以看出,

char g_name[]="123";
 80483ca:	a1 e5 84 04 08       	mov    0x80484e5,%eax
 80483cf:	89 45 f4             	mov    %eax,-0xc(%ebp)

  是把字符串字面量在全局常量区的内容复制到栈中的字符数组。字符串字面量的地址是0x80484e5,字符数组的地址是-0xc(%ebp),在栈中。

代码2,仅仅将代码1中的

char g_name[]="123"改为
char *g_name="123";

运行后发生段错误,

反汇编得到
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]='';  //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
", 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
}  

 可以看出

char *g_name="123";
 80483ca:	c7 45 f4 e0 84 04 08 	movl   $0x80484e0,-0xc(%ebp)

是将字符串字面量的地址赋值给了栈中的指针变量g_name;后面通过指针变量g_name访问时,由于修改全局常量区的数据,所以发生段错误。


结论:

注意:

指针方式创建的字符数组,是常量字符串,指针指向的内容是没法更改的;方括号([])方式创建的字符数组仅仅是变量,内容可以更改。


原文地址:https://www.cnblogs.com/lh03061238/p/13445830.html