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

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'; 因为是constreturn 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'; 因为是constreturn 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;// 123cout << p5 << std::endl;// 123cout << p6 << std::endl;// 123cout << a1 << std::endl;// 123cout << a2 << std::endl;// 123delete[] p4;
}

写在后面

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL题目分析:打折日期交叉问题--计算品牌总优惠天数

在电商平台的数据分析中&#xff0c;处理品牌促销活动的日期交叉问题是一个挑战。本文将介绍几种高级SQL技巧&#xff0c;用于准确计算每个品牌的总优惠天数&#xff0c;即使在存在日期交叉的情况下。 问题背景 我们有一个促销活动表 shop_discount&#xff0c;记录了不同品牌…

docker-compose 部署 flink

下载 flink 镜像 [rootlocalhost ~]# docker pull flink Using default tag: latest latest: Pulling from library/flink 762bedf4b1b7: Pull complete 95f9bd9906fa: Pull complete a880dee0d8e9: Pull complete 8c5deab9cbd6: Pull complete 56c142282fae: Pull comple…

【二叉树进阶】二叉搜索树

目录 1. 二叉搜索树概念 2. 二叉搜索树的实现 2.1 创建二叉搜索树节点 2.2 创建实现二叉搜索树 2.3 二叉搜索树的查找 2.4 二叉搜索树的插入 2.5 二叉搜索树的删除 2.6 中序遍历 2.7 完整代码加测试 3. 二叉搜索树的应用 3.1 K模型&#xff1a; 3.2 KV模型&#xf…

【C++11】可变参数模板

【C11】可变参数模板 一、可变参数模板概念以及定义方式 ​ 在C11之前&#xff0c;类模板和函数模板只能含有固定数量的模板参数&#xff0c;c11增加了可变模板参数特性&#xff1a;允许模板定义中包含0到任意个模板参数。声明可变参数模板时&#xff0c;需要在typename或cla…

数据在内存中的存储方式

前言&#xff1a;已经好久没更新了&#xff0c;开学之后学习编程的时间少了很多。因此&#xff0c;已经好几个礼拜都没有写文章了。 在讲解操作符的时候&#xff0c;我们就已经学习过了整数在内存中的存储方式。若有不懂的伙伴可以前往操作符详解进行学习。今天我们主要来学习…

[数据集][目标检测]智慧交通铁路人员危险行为躺站坐检测数据集VOC+YOLO格式3766张4类别

图片数量(jpg文件个数)&#xff1a;3766 标注数量(xml文件个数)&#xff1a;3766 标注数量(txt文件个数)&#xff1a;3766 标注类别数&#xff1a;4 标注类别名称:["sitting","sleeping","standing","track"] 每个类别标注的框数&…

NC 矩阵最长递增路径

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个 n 行…

<Linux> 进程间通信

目录 一、进程间通信介绍 1. 进程间通信概念 2. 进程间通信目的 3. 进程间通信的本质 4. 进程间通信发展 5. 进程间通信分类 管道&#xff08;文件缓冲区&#xff09; System V IPC POSIX IPC 二、管道 1. 匿名管道 1.1 匿名管道原理 1.2 pipe系统调用 1.3 匿名管道的使用 1.4…

Java项目基于docker 部署配置

linux新建文件夹 data cd datatouch Dockerfilesudo vim Dockerfile# 使用一个基础的 Java 镜像&#xff08;根据自己项目中使用的是什么jdk版本设置&#xff0c;用于拉取执行jar包的jdk环境&#xff09; FROM openjdk:8# 指定工作目录 VOLUME /data# 复制应用程序的 JAR 文件…

超详解——​深入理解Python中的位运算与常用内置函数/模块——基础篇

目录 ​编辑 1.位运算 2.常用内置函数/模块 math模块 random模块 decimal模块 常用内置函数 3.深入理解和应用 位运算的实际应用 1.权限管理 2.位图 3.图像处理 2.math模块的高级应用 统计计算 几何计算 总结 1.位运算 位运算是对整数在内存中的二进制表示进行…

nginx负载均衡(轮询与权重)

文章目录 1. nginx的介绍2. nginx使用场景3. nginx在windows的下载与安装4. nginx的简单使用5. nginx进行轮询测试6. nginx进行权重测试7. 总结 1. nginx的介绍 Nginx&#xff08;engine x&#xff09;是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也是一个开源的、…

CSS 响应式设计(补充)——WEB开发系列36

随着移动设备的普及&#xff0c;网页设计的焦点逐渐转向了响应式设计。响应式设计不仅要求网页在各种屏幕尺寸上良好展示&#xff0c;还要适应不同设备的特性。 一、响应式设计之前的灵活布局 在响应式设计流行之前&#xff0c;网页布局通常是固定的或流动的。固定布局使用固定…

MySQL练手题--体育馆的人流量(困难)

一、准备工作 Create table If Not Exists Stadium (id int, visit_date DATE NULL, people int); Truncate table Stadium; insert into Stadium (id, visit_date, people) values (1, 2017-01-01, 10); insert into Stadium (id, visit_date, people) values (2, 2017-01-02…

MouseArea元素

常用信号 onClicked&#xff0c;鼠标点击onPressed&#xff0c;鼠标按下onReleased&#xff0c;鼠标释放 import QtQuickWindow {width: 640height: 480visible: truetitle: qsTr("Hello World")Rectangle{id:rectwidth: 100height: 100color:"red"MouseA…

视频监控平台是如何运作的?EasyCVR视频汇聚平台的高效策略与实践

随着科技的飞速发展&#xff0c;视频监控平台在社会安全、企业管理、智慧城市构建等领域发挥着越来越重要的作用。一个高效的视频监控平台&#xff0c;不仅依赖于先进的硬件设备&#xff0c;更离不开强大的视频处理技术作为支撑。这些平台集成了多种先进的视频技术&#xff0c;…

Redis集群_cluster

cluster集群 cluster翻译就是集群&#xff0c;所以cluster集群也叫做redis集群相比于哨兵模式&#xff0c;cluster集群能支持扩容&#xff0c;并且无需额外的节点来监控状态&#xff0c;所以使用这种模式集群的系统会用的更多些redis cluster采用的是去中心化网络拓扑架构&…

git push : RPC failed; HTTP 400 curl 22 The requested URL returned error: 400

git push 出现RPC failed; HTTP 400 curl 22 The requested URL returned error: 400 问题 git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (10/10), done. error: RPC …

漫画元素检测系统源码分享

漫画元素检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

【开源分享】vsomeip 安装、编译、运行步骤笔记

文章目录 1. 摘要2. 安装、编译2.1 开发环境说明2.2 安装依赖2.3 获取代码2.4 编译代码2.5 安装 3. 测试验证参考 1. 摘要 本文主要描述 vsomeip 的安装、编译与运行步骤。下载源码&#xff0c;安装必要依赖&#xff0c;如Boost和CMake。通过CMake配置编译 vsomeip 库&#xf…

【C++】unordered系列

前言&#xff1a; 在C11及以后的标准中&#xff0c;unordered容器是标准模板库&#xff08;STL&#xff09;的一部分&#xff0c;提供了高效的数据结构选项&#xff0c;适用于需要快速查找和插入操作的场景。 unordered通常与关联容器一起使用&#xff0c;特别是unordered_map和…