C语言:字符串字面量及其保存位置
相关阅读
C语言
https://blog.csdn.net/weixin_45791458/category_12423166.html?spm=1001.2014.3001.5482
虽然C语言中不存在字符串类型,但依然可以通过数组或指针的方式保存字符串,但字符串字面量却没有想象的这么简单,本文就将对此进行讨论。
字符串字面量保存在静态存储区,所谓静态存储区即表示其值在程序执行前就已存在于可执行文件中。如果更详细地说,字符串字面量可能保存在.rodata section中,所以当尝试使用指针改变一个字符串字面量的值时会出现段错误。需要特别说明的是上面所说的字符串字面量的位置没有任何限制,可以是在函数内,也可以是在函数外,如下面的代码所示。
例1
#include <stdio.h>
char *ptr1 = "abcde"; //"abcde"被添加到.rodata section
int main()
{char *ptr2 = "ABCDE"; //"ABCDE"被添加到.rodata sectionprintf("This is a string"); //"This is a string"被添加到.rodata section
}
现在我们可以使用gcc编译链接成可执行程序,如下所示。
$gcc test.c -o test
然后使用readelf命令读取二进制可执行文件test中的信息,注意这里添加了-S选项表示只输出section头的相关信息。
$readelf -S test
There are 31 section headers, starting at offset 0x36c0:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .interp PROGBITS 0000000000000318 00000318000000000000001c 0000000000000000 A 0 0 1[ 2] .note.gnu.pr[...] NOTE 0000000000000338 000003380000000000000030 0000000000000000 A 0 0 8[ 3] .note.gnu.bu[...] NOTE 0000000000000368 000003680000000000000024 0000000000000000 A 0 0 4[ 4] .note.ABI-tag NOTE 000000000000038c 0000038c0000000000000020 0000000000000000 A 0 0 4[ 5] .gnu.hash GNU_HASH 00000000000003b0 000003b00000000000000024 0000000000000000 A 6 0 8[ 6] .dynsym DYNSYM 00000000000003d8 000003d800000000000000a8 0000000000000018 A 7 1 8[ 7] .dynstr STRTAB 0000000000000480 00000480000000000000008f 0000000000000000 A 0 0 1[ 8] .gnu.version VERSYM 0000000000000510 00000510000000000000000e 0000000000000002 A 6 0 2[ 9] .gnu.version_r VERNEED 0000000000000520 000005200000000000000030 0000000000000000 A 7 1 8[10] .rela.dyn RELA 0000000000000550 0000055000000000000000d8 0000000000000018 A 6 0 8[11] .rela.plt RELA 0000000000000628 000006280000000000000018 0000000000000018 AI 6 24 8[12] .init PROGBITS 0000000000001000 00001000000000000000001b 0000000000000000 AX 0 0 4[13] .plt PROGBITS 0000000000001020 000010200000000000000020 0000000000000010 AX 0 0 16[14] .plt.got PROGBITS 0000000000001040 000010400000000000000010 0000000000000010 AX 0 0 16[15] .plt.sec PROGBITS 0000000000001050 000010500000000000000010 0000000000000010 AX 0 0 16[16] .text PROGBITS 0000000000001060 00001060000000000000011b 0000000000000000 AX 0 0 16[17] .fini PROGBITS 000000000000117c 0000117c000000000000000d 0000000000000000 AX 0 0 4[18] .rodata PROGBITS 0000000000002000 000020000000000000000021 0000000000000000 A 0 0 4[19] .eh_frame_hdr PROGBITS 0000000000002024 000020240000000000000034 0000000000000000 A 0 0 4[20] .eh_frame PROGBITS 0000000000002058 0000205800000000000000ac 0000000000000000 A 0 0 8[21] .init_array INIT_ARRAY 0000000000003db8 00002db80000000000000008 0000000000000008 WA 0 0 8[22] .fini_array FINI_ARRAY 0000000000003dc0 00002dc00000000000000008 0000000000000008 WA 0 0 8[23] .dynamic DYNAMIC 0000000000003dc8 00002dc800000000000001f0 0000000000000010 WA 7 0 8[24] .got PROGBITS 0000000000003fb8 00002fb80000000000000048 0000000000000008 WA 0 0 8[25] .data PROGBITS 0000000000004000 000030000000000000000018 0000000000000000 WA 0 0 8[26] .bss NOBITS 0000000000004018 000030180000000000000008 0000000000000000 WA 0 0 1[27] .comment PROGBITS 0000000000000000 00003018000000000000002d 0000000000000001 MS 0 0 1[28] .symtab SYMTAB 0000000000000000 000030480000000000000378 0000000000000018 29 18 8[29] .strtab STRTAB 0000000000000000 000033c000000000000001e1 0000000000000000 0 0 1[30] .shstrtab STRTAB 0000000000000000 000035a1000000000000011a 0000000000000000 0 0 1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),D (mbind), l (large), p (processor specific)
从上面的信息中可以找到.rodata section的offset(即该section在二进制文件中的偏移)为2000。
下面使用hexdump命令查看二进制可执行文件文件test中的内容,其中-C选项用于以十六进制单个字节的方式输出并将对应的ASCII码显示在右边。
$hexdump -C test
......
00002000 01 00 02 00 61 62 63 64 65 00 41 42 43 44 45 00 |....abcde.ABCDE.|
00002010 54 68 69 73 20 69 73 20 61 20 73 74 72 69 6e 67 |This is a string|
00002020 00 00 00 00 01 1b 03 3b 30 00 00 00 05 00 00 00 |.......;0.......|
......
通过以上我们知道字符串字面量一般是保存在可执行文件的.rodata section中,但是否所有字符串字面量都会保存在.rodata section中呢?答案是否定的,如下例所示。
例2
char array1[6] = "aaaaaa"; //"aaaaaa"被添加到.data section作为全局数组的初始值
const char array2[6] = "bbbbbb" //"bbbbbb"被添加到.rodata section,因为它是只读的数据
int main()
{const char array3[6] = "cccccc" //"cccccc"被添加到.rodata section,无论是否有const修饰
}
对例2结果的验证在此跳过,交给读者进行。下面进行结果的说明,在上面的代码中,array1是一个有字符串初始值的全局数组,字符串字面量会直接添加到.data section中,即保存全局变量的section,且并不会在.rodata section保存。但array2是一个只读的有字符串初始值的全局数组,字符串字面量还是会被添加到.rodata section。至于array3,它和例1一样,无论是否有const修饰,字符串字面量都是被放在.rodata section。但要注意的是,array3与array2和array1不同,这个数组是保存在栈上的,而数组的值"cccccc"是在程序执行前就在可执行代码中的.rodata段的。在进入main函数后,栈上会开辟空间给array3,然后将.rodata区的代码复制一份到array3栈上的空间,在退出main函数后,栈上空间被自动回收。
相关文章:
C语言:字符串字面量及其保存位置
相关阅读 C语言https://blog.csdn.net/weixin_45791458/category_12423166.html?spm1001.2014.3001.5482 虽然C语言中不存在字符串类型,但依然可以通过数组或指针的方式保存字符串,但字符串字面量却没有想象的这么简单,本文就将对此进行讨论…...
【开源】基于Vue+SpringBoot的新能源电池回收系统
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回收机构模块2.4 电池订单模块2.5 客服咨询模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 E-R 图设计 四、系统展示五、核心代码5.1 增改电池类型5.2 查询电池品类5.3 查询电池回…...
共享和独享的区别是什么?有必要用独享IP吗?
通俗地讲,共享IP就像乘坐公共汽车一样,您可以到达目的地,但将与其他乘客共享旅程,座位很可能是没有的。独享IP就像坐出租车一样,您可以更快到达目的地,由于车上只有您一个人,座位是您一个人专用…...
leetcode——打家劫舍问题汇总
本章汇总一下leetcode中的打家劫舍问题,使用经典动态规划算法求解。 1、梦开始的地方——打家劫舍(★) 本题关键点就是不能在相邻房屋偷东西。 采用常规动态规划做法: 根据题意设定dp数组,dp[i]的含义为:…...
Java经典框架之Spring MVC
Spring MVC Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. Spring MVC 入门案例 2. 基…...
Golang make vs new
文章目录 1.简介2.区别3.new 可以初始化 slice,map 和 channel 吗?4.make 可以初始化其他类型吗?5.小结参考文献 1.简介 在 Go 语言中,make 和 new 是两个用于创建对象的内建函数,但它们有着不同的用途和适用范围。 …...
Arthas
概述 Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会…...
IP代理科普| 共享IP还是独享IP?两者的区别与优势
通俗地讲,共享IP就像乘坐公共汽车一样,您可以到达目的地,但将与其他乘客共享旅程,座位很可能是没有的。独享IP就像坐出租车一样,您可以更快到达目的地,由于车上只有您一个人,座位是您一个人专用…...
龙芯loongarch64服务器编译安装tensorflow-io-gcs-filesystem
前言 安装TensorFlow的时候,会出现有些包找不到的情况,直接使用pip命令也无法安装,比如tensorflow-io-gcs-filesystem,安装的时候就会报错: 这个包需要自行编译,官方介绍有限,这里我讲解下 编译 准备 拉取源码:https://github.com/tensorflow/io.git 文章中…...
开源持续测试平台Linux MeterSphere本地部署与远程访问
文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…...
Kubernetes(K8S)快速入门
概述 在本门课程中,我们将会学习K8S一些非常重要和核心概念,已经操作这些核心概念对应组件的相关命令和方式。比如Deploy部署,Pod容器,调度器,Service服务,Node集群节点,Helm包管理器等等。 在…...
将遗留系统分解为微服务:第 2 部分
在当今不断发展的技术环境中,从整体架构向微服务的转变对于许多企业来说都是一项战略举措。这在报销计算系统领域尤其重要。正如我在上一篇文章第 1 部分应用 Strangler 模式将遗留系统分解为微服务-CSDN博客中提到的,让我们探讨如何有效管理这种转变。 …...
RK3588平台开发系列讲解(AI 篇)RKNN-Toolkit2 模型的加载转换
文章目录 一、Caffe 模型加载接口二、TensorFlow 模型加载接口三、TensorFlowLite 模型加载接口四、ONNX 模型加载五、DarkNet 模型加载接口六、PyTorch 模型加载接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 RKNN-Toolkit2 目前支持 Caffe、TensorFlow、Tensor…...
CNVD原创漏洞审核和处理流程
一、CNVD原创漏洞审核归档和发布主流程 (一)审核和归档流程 审核流程分为一级、二级、三级审核,其中一级审核主要对提交的漏洞信息完整性进行审核,漏洞符合可验证(通用型漏洞有验证代码信息或多个互联网实例、事件型…...
【java爬虫】基于springboot+jdbcTemplate+sqlite+OkHttp获取个股的详细数据
注:本文所用技术栈为:springbootjdbcTemplatesqliteOkHttp 前面的文章我们获取过沪深300指数的成分股所属行业以及权重数据,本文我们来获取个股的详细数据。 我们的数据源是某狐财经,接口的详细信息在下面的文章中,本…...
智能优化算法应用:基于人工兔算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于人工兔算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于人工兔算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工兔算法4.实验参数设定5.算法结果6.参考文…...
【ubuntu 22.04】安装vscode并配置正常访问应用商店
注意:要去vscode官网下载deb安装包,在软件商店下载的版本不支持输入中文 在ubuntu下用火狐浏览器无法访问vscode官网,此时可以手动进行DNS解析,打开DNS在线查询工具,解析以下主机地址(复制最后一个IP地址&a…...
K8s出现问题时,如何排查解决!
K8s问题的排查 1. POD启动异常、部分节点无法启动pod2. 审视集群状态3. 追踪事件日志4. 聚焦Pod状态5. 检查网络连通性6. 审视存储配置7. 研究容器日志8. K8S集群网络通信9. 问题:Service 是否通过 DNS 工作?10. 总结1、POD启动异常、部分节点无法启动p…...
2015年第四届数学建模国际赛小美赛B题南极洲的平均温度解题全过程文档及程序
2015年第四届数学建模国际赛小美赛 B题 南极洲的平均温度 原题再现: 地表平均温度是反映气候变化和全球变暖的重要指标。然而,在以前的估计中,在如何界定土地平均数方面存在一些方法上的差异。为简单起见,我们只考虑南极洲。请建…...
npm常见错误
三个方面 1. npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! phantomjs-prebuilt2.1.15 install: node install.js npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the phantomjs-prebuilt2.1.15 install script. np…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
