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'; 因为是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;
}

写在后面

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql 8.0 时间维度表生成(可运行)

文章目录 mysql 8.0 时间维度表生成实例时间维度表的作用时间维度表生成技术细节使用时间维度表的好处 mysql 8.0 时间维度表生成实例 时间维度表的作用 dim_times&#xff08;时间维度表&#xff09;在数据仓库&#xff08;Data Warehouse&#xff09;中的作用至关重要。作为…

Vite + Electron 时,Electron 渲染空白,静态资源加载错误等问题解决

问题 如果在 electron 里直接引入 vite 打包后的东西&#xff0c;那么有些资源是请求不到的 这是我的引入方式 根据报错&#xff0c;我们来到 vite 打包后的路径看一看 &#xff0c;修改一下 dist 里的文件路径试了一试 修改后的样子&#xff0c;发现是可以的了 原因分析 …

Java-idea小锤子图标

这一版的idea小锤子图标其实就在这里 点进去就找到了~

航空航司reese84逆向

reese84逆向 Reese84 是一种用于保护网站防止自动化爬虫抓取的防护机制&#xff0c;尤其是在航空公司网站等需要严格保护数据的平台上广泛使用。这种机制通过复杂的指纹识别和行为分析技术来检测和阻止非人类的互动。例如&#xff0c;Reese84 可以通过分析访问者的浏览器指纹、…

java技术栈介绍

Java技术栈是一个庞大而丰富的生态系统&#xff0c;它包含了从基础语言特性到高级框架、库和工具的整个集合。这个技术栈为开发者提供了构建各种类型应用&#xff08;包括企业级应用、Web应用、移动应用、大数据应用等&#xff09;所需的全部组件。以下是对Java技术栈的一个更详…

Java 技巧 如何在IDEA2024 中快速打出System.out.println();

1.基本用法 键入sout回车 回车后变成&#xff1a; 2.打印变量 快速打印变量,以打印变量名为set为例&#xff0c;set.sout回车&#xff0c; 回车后变成

YOLOv8 人体姿态估计动作识别关键点检测(代码+教程)

YOLOv8 人体姿态判断 项目介绍 YOLOv8 人体姿态判断 是一个基于最新YOLOv8模型的深度学习项目&#xff0c;旨在识别和分析人体姿态。该项目利用先进的计算机视觉技术和深度学习框架&#xff0c;通过摄像头捕捉实时图像或处理存储图像&#xff0c;识别人体的关键点&#xff0c…

ubuntu服务器版NVIDIA驱动失效解决方案

ubuntu服务器版NVIDIA驱动失效解决方案 1. 问题描述2. 解决方法--卸载并重新安装最新版显卡驱动cudacudnn2.1 卸载显卡驱动2.2 重新安装最新版显卡驱动cudacudnn2.2.1 显卡驱动2.2.2 cuda2.2.3 cuda安装cudnn 1. 问题描述 在终端输入nvidia-smi&#xff0c;输出如下&#xff1…

安全工具 | 使用Burp Suite的10个小tips

Burp Suite 应用程序中有用功能的集合 img Burp Suite 是一款出色的分析工具&#xff0c;用于测试 Web 应用程序和系统的安全漏洞。它有很多很棒的功能可以在渗透测试中使用。您使用它的次数越多&#xff0c;您就越发现它的便利功能。 本文内容是我在测试期间学到并经常的主要…

oracle 使用 PL/SQL Developer创建表并插入单条、多条数据

第一步&#xff1a;使用工具创建表&#xff08;前提是库已经创建好了&#xff09;&#xff1a;在当前用户下找到Tables 然后点击并右键&#xff0c;点击新建 写上表名&#xff0c;写上表名的注释 第二步添加字段&#xff1a;点击列&#xff0c;然后分别写上你自己需要的字段及名…

在线查看 Android 系统源代码 AOSPXRef and AndroidXRef

在线查看 Android 系统源代码 AOSPXRef and AndroidXRef 1. AOSPXRef1.1. http://aospxref.com/android-14.0.0_r2/1.2. build/envsetup.sh 2. AndroidXRef2.1. http://androidxref.com/9.0.0_r3/2.2. build/envsetup.sh 3. HELLO AndroidReferences 1. AOSPXRef http://aospx…

QT项目添加资源文件

效果 1.先将图片等资源文件复制到QT项目源码目录中。 2.再添加资源文件 打开资源文件编辑 全选文件 代码

Leetcode—740. 删除并获得点数【中等】(unordered_map+set+sort)

2024每日刷题&#xff08;162&#xff09; Leetcode—740. 删除并获得点数 算法思想 实现代码 class Solution { public:int deleteAndEarn(vector<int>& nums) {unordered_map<int, int> freq;set<int> st;sort(nums.begin(), nums.end());int n num…

MySQL —— 视图

概念 视图是一张虚拟的表&#xff0c;它是基于一个或多个基本表或其他视图的查询结果集。 视图本身不存储数据&#xff0c;而是通过执行查询来动态生成数据&#xff0c;用户可以像操作普通表一样使用视图来进行查询更新与管理等操作。 视图本身也不占用物理存储空间&#xf…

【python因果推断库16】使用 PyMC 模型进行回归拐点设计

目录 例子 1 - 连续分段线性函数 import arviz as az import matplotlib.pyplot as plt import numpy as np import pandas as pdimport causalpy as cp %load_ext autoreload %autoreload 2 %config InlineBackend.figure_format retina seed 42 rng np.random.default_rn…

Android中的冷启动,热启动和温启动

在App启动方式中分为三种&#xff1a;冷启动&#xff08;cold start&#xff09;、热启动&#xff08;hot start&#xff09;、温启动&#xff08;warm start&#xff09; 冷启动&#xff1a; 系统不存在App进程&#xff08;App首次启动或者App被完全杀死&#xff09;时启动A…

AcWing算法基础课-789数的范围-Java题解

大家好&#xff0c;我是何未来&#xff0c;本篇文章给大家讲解《AcWing算法基础课》789 题——数的范围。本文详细解析了一个基于二分查找的算法题&#xff0c;题目要求在有序数组中查找特定元素的首次和最后一次出现的位置。通过使用两个二分查找函数&#xff0c;程序能够高效…

Mysql InnoDB 存储引擎简介

InnoDB 存储引擎是 Mysql 的默认存储引擎&#xff0c;它是由 Innobase Oy 公司开发的 Mysql 为什么默认使用 InnoDB 存储引擎 InnoDB 是一款兼顾高可靠性和高性能的通用存储引擎 在 Mysql 5.5 版本之前&#xff0c;默认是使用 MyISAM 存储引擎&#xff0c;在 5.5 及其之后版…

车型展示+接驳体验!苏州金龙海格客车闪耀汉诺威商用车展

德国当地时间9月16日&#xff0c;IAA汉诺威商用车展媒体日活动在德国汉诺威展览中心开幕。该展会自1897年首次举办以来&#xff0c;已有超过一个世纪的历史&#xff0c;是全球历史最长、规模最大、最具影响力的专业商用车展之一&#xff0c;更是世界商用车行业技术创新和发展趋…

实战案例(5)防火墙通过跨三层MAC识别功能控制三层核心下面的终端

如果网关是在核心设备上面&#xff0c;还能用MAC地址进行控制吗&#xff1f; 办公区域的网段都在三层上面&#xff0c;防火墙还能基于MAC来控制吗&#xff1f; 采用正常配置模式的步骤与思路 &#xff08;1&#xff09;配置思路与上面一样 &#xff08;2&#xff09;与上面区…