[cpp] view plaincopy
  1. char * s1 = "abcd";
  2. s1[0] = 'm';//segment fault

上面代码在gcc下编译运行将报段错误。

然而,

[cpp] view plaincopy
  1. char s1[] = "abcd";
  2. s1[0] = 'm';

这段代码则能够正确运行。其中包含的原理是char* 和 char[],在内存分配上的机制差异。

对于char *  s = "abcd";来说, 编译器会将字符串字面量当作常量数据处理,存放在.rodata段,这样以来,s将指向.rodata段中的某处内存,

因此对该段内存的修改会引起段错误。(另,printf等格式化字符串函数中的format string 如"%d"等也会被放在.rodata中。)

对于char s1[] = "abcd";来说,"abcd"是在栈上分配内存,使用mov指令直接将值写入栈上对应内存。

使用下面代码来验证上面的描述:

[cpp] view plaincopy
  1. #include <stdio.h>
  2. int main()
  3. {
  4. char * s1 = "abcd";
  5. char s2[] = "efghef";
  6. }

查看汇编指令:

[plain] view plaincopy
  1. cString.o:     file format elf32-i386
  2. Contents of section .text:
  3. 0000 5589e583 e4f083ec 1065a114 00000089  U........e......
  4. 0010 44240c31 c0c70424 00000000 c7442405  D$.1...$.....D$.
  5. 0020 65666768 66c74424 096566c6 44240b00  efghf.D$.ef.D$..
  6. 0030 8b54240c 65331514 00000074 05e8fcff  .T$.e3.....t....
  7. 0040 ffffc9c3                             ....
  8. <span style="color:#3333FF;">Contents of section .rodata:
  9. 0000 61626364 00                          abcd.  </span>
  10. Contents of section .comment:
  11. 0000 00474343 3a202855 62756e74 752f4c69  .GCC: (Ubuntu/Li
  12. 0010 6e61726f 20342e35 2e322d38 7562756e  naro 4.5.2-8ubun
  13. 0020 74753429 20342e35 2e3200             tu4) 4.5.2.
  14. Disassembly of section .text:
  15. 00000000 <main>:
  16. 0:   55                      push   %ebp
  17. 1:   89 e5                   mov    %esp,%ebp
  18. 3:   83 e4 f0                and    $0xfffffff0,%esp
  19. 6:   83 ec 10                sub    $0x10,%esp
  20. 9:   65 a1 14 00 00 00       mov    %gs:0x14,%eax
  21. f:   89 44 24 0c             mov    %eax,0xc(%esp)
  22. 13:   31 c0                   xor    %eax,%eax
  23. 15:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  24. <span style="color:#3333FF;"> 1c:  c7 44 24 05 65 66 67    movl   $0x68676665,0x5(%esp)
  25. 23:   68
  26. 24:   66 c7 44 24 09 65 66    movw   $0x6665,0x9(%esp)</span>
  27. 2b:   c6 44 24 0b 00          movb   $0x0,0xb(%esp)
  28. 30:   8b 54 24 0c             mov    0xc(%esp),%edx
  29. 34:   65 33 15 14 00 00 00    xor    %gs:0x14,%edx
  30. 3b:   74 05                   je     42 <main+0x42>
  31. 3d:   e8 fc ff ff ff          call   3e <main+0x3e>
  32. 42:   c9                      leave
  33. 43:   c3                      ret

前面用蓝色标出部分为char*声明的字符串。后面蓝色标出部分位char[]字符串数组。

此外,对于函数如strcpy(s3,"abcd"),这样的调用,参数传入字符串常量的都是存储在.rodata段中的。

转载于:https://www.cnblogs.com/leoluoisacoder/p/3724354.html

char* 和char[] 内存分配的区别(转载)相关推荐

  1. MySQL性能优化之char、varchar、text的区别(转载)

    参考:https://dev.mysql.com/doc/refman/8.0/en/string-type-overview.html 在存储字符串时, 可以使用char.varchar或者text ...

  2. C++和C语言中的动态内存分配的区别

    在C语言和C++中都会用到动态内存的申请分配的问题,两者之间申请动态内存分配还是区别的. 在C++中的动态内存的分配 1.C++通过new关键字进行动态内存的分配.new关键字是C++内置的一个关键字 ...

  3. C/C++——动态内存分配

    动态内存分配,就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法.动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序 ...

  4. Visual Studio的.NET内存分配分析器解析

    Visual Studio 2012拥有丰富的有价值的功能,以至于我听到开发者反馈的需要的新功能新版本已经有了.另外,我听到开发人员询问具体的功能的某个特性,实际上他真正需要的是另外一个功能点. 上面 ...

  5. [转载]内存分配 知识,全局,局部,静态变量

    [转载]内存分配 知识,全局,局部,静态变量 预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变 ...

  6. JVM之JVM内存区域与内存分配(转载)

    2019独角兽企业重金招聘Python工程师标准>>> 先来看看JVM运行时候的内存区域 大多数 JVM 将内存区域划分为 Method Area(Non-Heap)(方法区),He ...

  7. 内存分配方式以及堆和栈的区别

    转载:https://blog.csdn.net/shanchangyi/article/details/51854795 对于一个程序要运行,涉及到的内存分配是一个首要问题,这里简单说一下一个简单的 ...

  8. [转载] JAVA 堆栈 堆 方法区 静态区 final static 内存分配 详解

    参考链接: 在Java中为静态最终static final变量分配值 转载来源:https://blog.csdn.net/peterwin1987/article/details/7571808 J ...

  9. 【转载】Java 内存分配全面浅析

    本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 本文转载自袭烽大神的博客,原文链接 ...

最新文章

  1. 看源码,我为什么推荐IDEA?
  2. 转:百万级访问量网站的技术准备工作
  3. 福师计算机导论在线作业一,福师《计算机导论》在线作业一..doc
  4. ios的 UIButton
  5. Jon Person教你如何用.NET/.NETCF写GPS应用程序。
  6. java中在做除法操作时,对有余数的结果进行取整
  7. JSP 标准标签库(JSTL)
  8. java多线程总结二:后台线程(守护线程)
  9. ftp服务器搭建遇到的问题
  10. 协议转换器主要是应用在哪些地方?
  11. 使用 C# 编程对RTF文档的支持
  12. java 静态线程_Java线程类静态本机void yield()方法(带示例)
  13. WebSocket API使用篇检测浏览器是否支持WebSocket(4)
  14. 南开大学20春计算机应用基础,南开大学-2020春学期《计算机应用基础》在线作业.txt.pdf...
  15. jquery 跨域_springboot解决js前端跨域问题,javascript跨域问题解决
  16. oracle全局高速缓存,Oracle技术之设置系统全局区SGA命令
  17. Thinkphp5.1整合支付宝APP支付
  18. CSS总结1-来自freecode
  19. Adobe PS常用快捷键
  20. iOS - 接入 Live2D

热门文章

  1. 我的四轴专用PID参数整定方法及原理
  2. 动态规划 - 买卖股票的最佳时机 III
  3. HDU Problem - 5918 Sequence I
  4. HDU Problem - 5976 Detachment(逆元,阶乘打表,数学)
  5. Kali 装机之后的各种操作
  6. pygame 学习check_event,game_function,alien_invasion等程序
  7. 计组-CPU的功能和基础结构
  8. 8086汇编常用指令(待解释)
  9. Master公式(计算递归复杂度)
  10. mysql 主备及时_MySQL高可用(二)主备延时如何解决?