当前位置: 首页 > news >正文

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;
}

写在后面

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 安卓BLE蓝牙通讯
  • Ubuntu搭建FTP服务器
  • K8s1.28 部署Dashboard获取登录信息
  • 【最新华为OD机试E卷-支持在线评测】最长连续子序列(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • 基于鸿蒙API10的RTSP播放器(七:亮度调节功能测试)
  • 基于微信小程序的宠物之家的设计与实现
  • 1. TypeScript基本语法
  • ‌移动管家手机智能控制汽车系统
  • 力扣刷题(6)
  • 唯徳知识产权管理系统 DownloadFileWordTemplate 文件读取漏洞复现
  • 【Linux】Ubuntu 22.04 shell实现MySQL5.7 tar 一键安装
  • LeetCode[中等] 合并区间
  • C++ | Leetcode C++题解之第400题第N位数字
  • unity3d入门教程六
  • [001-03-007].第07节:Redis中的管道
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【个人向】《HTTP图解》阅后小结
  • co.js - 让异步代码同步化
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Git初体验
  • Rancher-k8s加速安装文档
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • windows下使用nginx调试简介
  • 基于组件的设计工作流与界面抽象
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 三栏布局总结
  • 深度学习在携程攻略社区的应用
  • 深入浅出webpack学习(1)--核心概念
  • 我是如何设计 Upload 上传组件的
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • $.ajax中的eval及dataType
  • (1) caustics\
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (Python第六天)文件处理
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (四)汇编语言——简单程序
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (一)Neo4j下载安装以及初次使用
  • (状压dp)uva 10817 Headmaster's Headache
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .netcore如何运行环境安装到Linux服务器
  • /bin/bash^M: bad interpreter: No such file or directory
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • @Value读取properties中文乱码解决方案
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择