zoukankan      html  css  js  c++  java
  • 字符串变量存储位置

    参考:

    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访问时,由于修改全局常量区的数据,所以发生段错误。


    结论:

    注意:

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

    
    
  • 相关阅读:
    Hibernate hql查询
    Hibernate Criteria的方法
    Hibernate笔记:HQL查询总结(二)——条件查询
    级联查询
    Hibernate HQL查询 总结
    JavaScript声明全局变量三种方式的异同
    javascript变量注意事项
    Hibernate的QBC检索方式
    C# 串口编程 SerialPort
    SPBasePermissions Modify Permission Levels (using bitwise operators)
  • 原文地址:https://www.cnblogs.com/lh03061238/p/13445830.html
Copyright © 2011-2022 走看看