C++ char*和char[] 可能指向的内存区域详解(附实验)

news2024/11/15 10:25:18

C++ char* 指向的内存区域详解

  • 写在前面
    • c++内存结构简介
    • 指针常量和常量指针简介
    • 情况一:char* 指向栈区内容
    • 情况二:char* 指向堆区内容
    • 情况三:char* 指向常量区内容
    • 情况四:char* 指向静态区内容
    • 情况五:char* 指向全局区内容
    • 测试代码
  • 写在后面

写在前面

之前调用别人的API,这个API返回一个const char*,当时就在想要不要自己copy一下这个值,因为不知道这个const char什么时候会被释放。于是自己下来探索了一下一个函数返回char时,char*可能指向的内存区域。

c++内存结构简介

C++ 内存主要分为栈区、堆区、全局区、静态区、常量区、代码区。
栈区:主要存放函数的形参、局部遍历
堆区:存放new出来的对象
全局区:存放全局变量
静态区:存放静态变量
常量区:存放常量(不包含局部常量)
我们知道字符串常量,例如"1234"、"abcd"这些值是存放在常量区的。
在这里插入图片描述

指针常量和常量指针简介

指针常量,例如const char * a,const修饰的是*,因此a指向的内容是不可以改的,也就是用a修改值是不可以的。而a本身是可以修改的,a可以指向其他地址。
常量指针,例如char * const a,const修饰的是a,因此a本身是是不可以改的,a不可以指向其他地址。而
a是可以修改的,也就是用*a修改值是可以的。
注意const char * a,只是代表a指向的内容是不可以改,不代表a一定指向的是常量,a也可以指向变量,只是无法修改这个变量的值,例如下面的语法都是合法的

char a[] = "123";
const char* p = a;//p指向变量
const char* p1 = "123";//p指向常量

情况一:char* 指向栈区内容

以下3种赋值方法在函数中定义时,a都是指向栈区。
编译器会把"123"从常量区复制一个副本出来然后赋值给char a[]

 char a[] = "123";//指向栈区
 char a[4];//指向栈区
    a[0] = '1';
    a[1] = '2';
    a[2] = '3';
    a[3] = '\0';
 const char a[] = "123";//指向栈区,不能用 a[0] = '1'; 因为是const

char* a = "123"呢?其实这种赋值方法是错误的,因为"123"的类型是常量const char *,无法讲常量赋值给变量的。
在这里插入图片描述

情况二:char* 指向堆区内容

用new 的方法,这时a指向的是堆区的1、2、3

 char* a = new char[4];//指向堆区
    a[0] = '1';
    a[1] = '2';
    a[2] = '3';
    a[3] = '\0';

情况三:char* 指向常量区内容

指向常量区,“123”就存放在常量区,因此a此时指向的是常量区

const char* a = "123";//指向常量区,不能用 a[0] = '1'; 因为是const

char* a = "123"呢?其实这种赋值方法是错误的,因为"123"的类型是常量const char *,无法讲常量赋值给变量的。
在这里插入图片描述

情况四:char* 指向静态区内容

static char a[] = "123";//指向静态区
static const char a[] = "123";//指向静态区

同样也无法static char* a = "123",原因和情况三一样,a是静态变量而"123"是常量,出发用 static const char* a = "123";

情况五:char* 指向全局区内容

讲变量定义在类外时,a2指向的就是全局区

char a2[] = "123"; //全局区
const char a1[] = "123"; //全局区

需要注意的是const char* a1 = "123";即便在类外定义,同样a1*指向的是常量区。

测试代码

用6个函数测试一下,可以看到指向栈区的指针都因为函数的出栈而被释放了。
在这里插入图片描述

char* Func1() {
    char a[] = "123";//指向栈区
    return a;
}

char* Func2() {
    char a[4];//指向栈区
    a[0] = '1';
    a[1] = '2';
    a[2] = '3';
    a[3] = '\0';
    return a;
}

const char* Func3() {
    const char a[] = "123";//指向栈区
    // 不能用 a[0] = '1'; 因为是const
    return a;
}

char* Func4() {
    char* a = new char[4];//指向堆区
    a[0] = '1';
    a[1] = '2';
    a[2] = '3';
    a[3] = '\0';
    return a;
}

const char* Func5() {
    const char* a = "123";//指向常量区
    // 不能用 a[0] = '1'; 因为是const
    return a;
}

char* Func6() {
    static char a[] = "123";//指向静态区
    return a;
}

const char* a1 = "123"; //指向全局区
const char a2[] = "123"; //指向全局区
const char* a3 = "123"; //指向常量区



int main(int argc, char const* argv[]) {
    char* p1 = Func1();
    const char* p11 = Func1();
    char* p2 = Func2();
    const char* p3 = Func3();
    const char* p4 = Func4();
    const char* p5 = Func5();
    const char* p6 = Func6();

    cout << p1 << std::endl; // 烫烫烫烫烫烫烫烫烫烫
    cout << p11 << std::endl;// 烫烫烫烫烫烫烫烫烫烫
    cout << p2 << std::endl;// 烫烫烫烫烫烫烫烫烫烫
    cout << p3 << std::endl;// 烫烫烫烫烫烫烫烫烫烫
    cout << p4 << std::endl;// 123
    cout << p5 << std::endl;// 123
    cout << p6 << std::endl;// 123
    cout << a1 << std::endl;// 123
    cout << a2 << std::endl;// 123

    delete[] p4;
}

写在后面

臭猴子,你说这山岭外的世界,究竟是什么样的
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2140654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scratch游戏-史诗忍者7免费下载

小虎鲸Scratch资源站-免费少儿编程Scratch作品源码,素材,教程分享网站! 作品描述&#xff1a; 在Scratch版本的《史诗忍者7》中&#xff0c;你需要穿越关卡&#xff0c;击败敌人并收集33个水果。通过灵活的操作和精准的攻击&#xff0c;逐步闯过重重难关。游戏中提供了丰富的技…

【GESP】C++一级练习BCQM3005,基本输出语句printf

一道基础练习题&#xff0c;练习基本输出语句printf。 BCQM3005 题目要求 描述 输出表达式1234∗5678的结果。 输入 无 输出 1234∗56787006652 输入样例 无 输出样例 1234 * 5678 7006652 全文详见个人独立博客&#xff1a;https://www.coderli.com/gesp-1-bcqm3005/ 【…

使用 SuperCraft AI 设计书橱模型的指南

在现代家居设计中&#xff0c;书橱不仅是存放书籍的地方&#xff0c;更是展示个人品味和风格的重要家具。借助 SuperCraft AI&#xff0c;你可以轻松设计出独一无二的书橱。以下是详细的步骤指南&#xff0c;帮助你从零开始设计一个理想的书橱。 1. 创建项目 首先&#xff0c…

【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)

目录 一、插入排序 算法思想 二、插入排序 算法步骤 四、复杂度分析 时间复杂度&#xff1a;O(n^2) 空间复杂度&#xff1a;O(1) 稳定性&#xff1a;稳定算法 五、应用场景 &#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏&#xff1a;探索数据结构…

node卸载流程

步骤&#xff1a; 1.开始中搜素”命令提示符“&#xff0c;并将其以”管理员身份运行“ 在弹出的框中输入cmd&#xff0c;并确认进入”命令提示符“ 2.在里面通过npm config list查看node相关文件路径&#xff0c; 并找到config from与prefix &#xff0c;后面对应的路径&…

element-plus的菜单组件el-menu

菜单是几乎是每个管理系统的软件系统中不可或缺的&#xff0c;element-plus提供的菜单组件可以快速完成大部分的菜单的需求开发&#xff0c; 该组件内置和vue-router的集成&#xff0c;使用起来很方便。 主要组件如下 el-menu 顶级菜单组件 主要属性 mode:决定菜单的展示模式…

visual studio给项目增加eigen库 手把手教程

Eigen是一个开源的C库&#xff0c;主要用来支持线性代数&#xff0c;矩阵和矢量运算&#xff0c;数值分析及其相关的算法。Eigen 除了C标准库以外&#xff0c;不需要任何其他的依赖包。Eigen库3.4.0版本的下载地址为&#xff1a; https://gitlab.com/libeigen/eigen/-/archive/…

qt-creator-10.0.2之后版本的jom.exe编译速度慢下来了

1、Qt的IDE一直在升级&#xff0c;qt-creator的新版本下载地址 https://download.qt.io/official_releases/qtcreator/ 2、本人一直用的是qt-creator-10.0.2版本&#xff0c;官网历史仓库可以下载安装包qt-creator-opensource-windows-x86_64-10.0.2.exe https://download.qt…

清华大佬自曝:接到了省烟草局的offer,我就拒掉了华为!结果华为立马给我申请了特殊涨薪,总包70w是烟草的2倍,这可如何是好?

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

Java设计模式—面向对象设计原则(四) ----->接口隔离原则(ISP) (完整详解,附有代码+案例)

文章目录 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.4 接口隔离原则(ISP) 接口隔离原则&#xff1a;Interface Segregation Principle&#xff0c;简称ISP 3.4.1 概述 客户端测试类不应该被迫依赖于它不使用的方法&#xff1b;一个类对另一个类的依赖应该建立在最小的接…

我国常见电压等级有哪些?来试试电压版2048让你轻松牢记

作为电气工程专业的小姜同学&#xff0c;平时喜欢敲点代码&#xff0c;前一阵做了一个电气特色的2048小游戏。既能缓解学习压力&#xff0c;又能让大家在玩之中把我国的电压等级牢记于心。 项目预览 功能描述 游戏方法与2048相同&#xff0c;根据我国标准的电压等级&#xff…

基于SpringBoot的人事管理系统【附源码】

基于SpringBoot的人事管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概述 4.2系统功能结构设计 4.3数据库设计 4.3.1数据库E-R图设计 4.3.2 数据库表结构设计 5 系统实现 5.1管理员功能介绍 5.1.1管理员登…

【Leetcode:1184. 公交站间的距离 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

PDF转JPG,奋斗汪的必备技能,你掌握了吗?

现在大家都用电脑手机处理文件&#xff0c;PDF和JPG是最常见的两种。PDF文件方便打印和分享&#xff0c;而JPG图片小巧清晰&#xff0c;适合在手机上看和发给别人。有时候&#xff0c;我们需要把PDF文件变成JPG图片&#xff0c;比如想把教材或报告变成图片&#xff0c;方便在手…

F28335 时钟及控制系统

1 F28335 系统时钟来源 1.1 振荡器OSC与锁相环PLL 时钟信号对于DSP来说是非常重要的,它为DSP工作提供一个稳定的机器周期从而使系统能够正常运行。时钟系统犹如人的心脏,一旦有问题整个系统就崩溃。DSP 属于数字信号处理器, 它正常工作也必须为其提供时钟信号。那么这个时钟…

树(森林)的定义和画图

目录 代码实现 “双亲表示法”顺序存储 “孩子表示法”链式存储 树的孩子表示法存储 v.s. 图的邻接表存储 v.s. 散列表的拉链法 v.s. 基数排序 “孩子兄弟表示法”链式存储 画图表示 “双亲表示法” 1.树 2.森林 “孩子表示法” 1.树 2.森林 “孩子兄弟表示法” …

SPI学习笔记

SPI SPI是一种同步串行通信接口规范&#xff0c;它允许一个主设备与一个或多个从设备进行全双工通信。SPI用于短距离通信&#xff0c;主要应用于嵌入式系统。 SPI通信过程 1.初始化&#xff1a;SPI主机首先将SS或CS线拉低&#xff0c;以选择特定的从设备并开始通信。 2.数据…

AI健身体能测试之基于paddlehub实现引体向上计数个数统计

【引体向上计数】 本项目使用PaddleHub中的骨骼检测模型human_pose_estimation_resnet50_mpii&#xff0c;进行人体运动分析&#xff0c;实现对引体向上的自动计数。 1. 项目介绍 人体运动分析是近几年许多领域研究的热点问题。在学科的交叉研究上&#xff0c;人体运动分析涉…

【电机仿真】全速域观测器零速旋转方波高频注入+低速+高速滑模观测器三段式启动

【电机仿真】全速域观测器零速脉振方波高频注入低速高速滑模观测器三段式启动 文章目录 前言一、零速——HFI方波注入1.HFI观测器2.静止坐标系——旋转高频电压信号3.PLL1锁相环4.PLL2锁相环 二、零速到中高速——HFI切SMO1.函数定义2.函数内部 三、中高速——SMO观测器1.SMO观…

卸载完mathtype后,删除word加载项中的mathtype

请参考博客“卸载完mathtype后&#xff0c;word加载项中还是有mathtype的解决方法_怎么删除word加载项里的mathtype-CSDN博客”以及 “安装卸载MathType经验解决MathType DLL找不到的问题——超实用_mathtype dll cannot-CSDN博客” 如果在删除.dotm文件时&#xff0c;删不掉…