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…...
抖音批量下载解决方案:模块化架构与智能降级策略
抖音批量下载解决方案:模块化架构与智能降级策略 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖…...
Linux 文件隐藏属性 chattr、lsattr 详解——锁住文件防误删(运维必备)
前言很多人只知道 chmod、chown 改权限,却不知道 Linux 还有隐藏文件属性。普通权限能被 root 绕过,而 chattr 隐藏属性可以 锁住文件,root 也无法删除、修改,是服务器防护、防误删、保护配置文件的核心命令。一、命令简介lsattr&…...
如何轻松地将数据从Android传输到 iPhone ?
从Android切换到 iPhone可能会让人不知所措,尤其是当你想在不重置新设备的情况下保持数据完整时。许多指南都侧重于恢复出厂设置,但在本文中,我们将探讨一些方法,让你能够无缝转移宝贵的数据,而无需清除 iPhone 上的所…...
九成企业担忧内部系统无法跟上高管薪酬管理需求
• 89%的高级人力资源(HR)、绩效奖励和薪酬负责人表示,企业内部技术无法跟上高管薪酬管理的需求 • 80%的受访者表示,过去三年中参与激励计划的人数有所增加 • 66%的受访者认为,依赖多家服务提供商是保持数据准确性和一致性的主要障碍 对于…...
选错bpp,你的App内存就炸了?聊聊图像格式、内存与性能的实战权衡
选错bpp,你的App内存就炸了?聊聊图像格式、内存与性能的实战权衡 在移动应用开发中,图像处理往往是性能瓶颈的重灾区。我曾见过一个社交类App因为图片加载策略不当,在低端设备上频繁触发OOM(内存溢出)崩溃。…...
Claude Code 架构深度解析:一文搞懂 Sub-Agent、Skill 与底层模型之间的协同机制
Claude Code 架构深度解析:一文搞懂 Sub-Agent、Skill 与底层模型之间的协同机制 Claude Code 凭什么成为 AI 编程工具市场占有率第一?本文深入拆解其内部四层架构——Skill 拦截层、Claude Code 编排器、Sub-Agent 执行层、底层大模型推理层——带你彻底…...
英雄年代怀旧版官网下载:正版复刻国战经典,热血回归
英雄年代怀旧版官网下载:正版复刻国战经典,热血回归《英雄年代怀旧版》(又名《风爆远征英雄年代怀旧版》)是安徽游昕运营、盛趣正版授权的复古国战 MMORPG 手游,1:1 复刻 2004 年端游原版内容,剔除魔神、暗…...
在OpenClaw项目中集成Taotoken实现Agent工作流
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在OpenClaw项目中集成Taotoken实现Agent工作流 对于使用OpenClaw框架构建AI Agent的开发者而言,一个稳定、便捷的模型服…...
Python运算符:比较运算符(等于不等等于大于小于)与返回值
Python运算符:比较运算符(等于不等等于大于小于)与返回值📚 本章学习目标:深入理解比较运算符(等于不等等于大于小于)与返回值的核心概念与实践方法,掌握关键技术要点,了…...
STM32F429实时IIR滤波避坑指南:arm_biquad_cascade_df1_f32的群延迟与状态缓存管理
STM32F429实时IIR滤波工程实践:群延迟补偿与状态缓存优化策略 在嵌入式信号处理领域,实时滤波是许多应用的核心需求。当我们在STM32F429平台上使用arm_biquad_cascade_df1_f32函数实现IIR滤波时,会遇到两个关键挑战:群延迟对实时性…...
