C语言——小知识和小细节17

一、未能给指针成功赋值

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void GetMemory(char* p)
{p = (char*)malloc(20 * sizeof(char));
}void Test()
{char* str = NULL;GetMemory(str);strcpy(str, "Hello World!");printf("%s\n", str);
}int main()
{Test();return 0;
}

这段代码实际上实现不了它所想要表达的功能,而且程序会崩溃。

因为对于 Test 函数,将 str 变量传给 GetMemory 函数,实际上只是值传递,将 NULL 传给了 p ,然后 malloc 函数分配好空间后,将内存块地址传给 p ,但在 GetMemory 函数完成调用后 p 这个变量会被销毁,而这里的内存块的地址没有传到 str 中,这里就导致了内存泄漏,因为 p 在这里就相当于 str 的拷贝,所以这里的 str 还是 NULL ,然后再 strcpy 这一句,传给 strcpy 一个空指针是错误的,可能是这一步导致程序崩溃。

要解决这个问题就可以使用二级指针,直接对 str 的只进行修改,将 malloc 函数分配的内存块的地址存到 str 中,然后再进行后面的步骤。

修改后:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void GetMemory(char** p)
{*p = (char*)malloc(20 * sizeof(char));
}void Test()
{char* str = NULL;GetMemory(&str);strcpy(str, "Hello World!");printf("%s\n", str);
}int main()
{Test();return 0;
}

运行结果:

二、程序占用的内存的分区

1、程序占用的内存的分区

在执行一个C/C++ 程序时,此程序拥有唯一的“内存四区”(栈区,堆区,全局区,代码区)

在某些情况下,常量区可能被认为是代码区的一部分,因为它们通常都是只读的,并且在程序编译时即被确定。由于这个原因,当讨论"内存四区"时,可能有意或无意地忽略了常量区,将其归入代码区。

一个由C/C++编译的程序占用的内存分为以下几个部分:栈区堆区全局区(静态区)文字常量区代码区

1)栈区(Stack):

栈是一块用于存储局部变量、函数参数、返回地址等的内存区域。它具有后进先出(LIFO)的特性,通常用来处理函数调用和局部变量的生命周期。每当函数被调用时,它的局部变量和一些控制信息会被推送到栈上,当函数返回时,这些信息会被弹出栈。

2)堆区(Heap):

堆区用于动态内存分配,通过调用如malloc, calloc, reallocfree等函数管理。堆的大小不是固定的,它可以在程序运行期间根据需要增长和缩小。

3)全局静态区:

全局静态区(数据段)通常分为初始化的数据段(.data)和未初始化的数据段(.bss)。.data段用于存储程序中的全局变量和静态变量,这些变量在程序启动时被初始化。未初始化的全局变量和静态变量通常存储在.bss段,因为它们在程序开始运行前会被自动初始化为零。

4)常量区:

这里存放的是常量字符串和其他常量数据。这部分数据通常也被放在只读的内存段中以防止修改。

5)代码区:

代码段,也称为文本段,包含程序的执行代码。这部分内存通常是只读的,以防止程序在运行时修改自己的指令。它包含了编译后的程序指令代码。

2、内存分区具体示意图

这里具体说一下内核空间和缓冲区,其他几部分已经在上面提到了。

1)内核空间:

内核空间是指在内存中保留给操作系统内核的部分。内核是操作系统中负责管理硬件资源、执行进程管理、内存管理、文件系统操作和其他基本系统操作的核心部分。内核空间与用户空间相对应,通常位于虚拟内存的高地址端。

  1. 隔离:内核空间与用户空间的隔离提供了安全性和稳定性。用户程序通常无法直接访问内核空间,这样即便用户程序崩溃或者有恶意行为,也不会直接影响到整个系统的稳定性。

  2. 特权级别:内核空间在处理器的特权级别上运行,这意味着它可以执行硬件操作和访问受保护的内存区域,而用户空间的程序则受到限制。

  3. 组成元素:内核空间包括了操作系统内核的代码、内核扩展、驱动程序、内核数据结构(如进程表、文件系统缓存、网络协议栈和硬件抽象层)等。

2)缓冲区:

缓冲区是内存中临时存放数据的区域,它的作用是协调处理器和其他硬件或软件之间速度不匹配的问题。用户级别的程序也可能使用缓冲区,如标准的I/O库(如C语言的stdio)会提供缓冲机制,以优化读写操作。

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

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

相关文章

Java网址url工具类

功能描述 无需引入三方依赖文本匹配网址&#xff08;支持多个&#xff09;网址解析&#xff08;包括协议、主机、路径、参数等&#xff09; package com.qiangesoft.image.utils;import org.springframework.util.Assert; import org.springframework.util.CollectionUtils;i…

Flutter笔记:Widgets Easier组件库(5)使用加减器

Flutter笔记 Widgets Easier组件库&#xff08;5&#xff09;&#xff1a;使用加减器 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress…

IO端子介绍及GPIO number计算

IO端子介绍 &#xff08;引脚&#xff0c;针脚&#xff09; 嵌入式系统的主芯片&#xff0c;有的IO资源少&#xff0c;有的IO资源多。 少的是这样的封装&#xff0c;IO管脚都在四周&#xff1b; 多的是这样的封装&#xff0c;IO 的PAD都在下面&#xff1a; MCU或MPU&#xff0c…

VS(Visual Studio)中查找项目里的中文字符

目录 正则表达式查找中文字符 正则表达式查找中文字符 在Visual Studio (VS) 中查找所有的中文字符&#xff0c;你可以使用其强大的查找和替换功能。不过&#xff0c;由于中文字符的范围非常广泛&#xff08;包括简体中文、繁体中文、日本汉字、韩国汉字等&#xff09;&#xf…

[1671]jsp教材管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 教材管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

springcloud自定义全局异常

自行创建一个实体类 /*** 全局异常处理类**/ ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class) ResponseBody public Result error(Exception e){e.printStackTrace(); return Result.fail();}/*** 自定义异常处理方法* param e * re…

亚马逊云科技AWS将推出数据工程师全新认证(有资料)

AWS认证体系最近更新&#xff0c;在原有12张的基础上&#xff0c;将在2023年11月27日添加第13张&#xff0c;数据工程师助理级认证(Data Engineer Associate)&#xff0c;并且在2024/1/12前半价(省75刀&#xff1d;544人民币。 原有的数据分析专家级认证(Data Analytics Specia…

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series 摘要 这段文字介绍了一个名为TS2Vec的通用框架&#xff0c;用于学习时间序列数据的表示&#xff0c;可以在任意语义层次上进行。与现有方法不同&#xff0c;TS2Vec通过对增强的上下文视图进行层次化…

Redis 实战1

SDS Redis 只会使用 C 字符串作为字面量&#xff0c; 在大多数情况下&#xff0c; Redis 使用 SDS &#xff08;Simple Dynamic String&#xff0c;简单动态字符串&#xff09;作为字符串表示。 比起 C 字符串&#xff0c; SDS 具有以下优点&#xff1a; 常数复杂度获取字符串…

每日一题(力扣213):打家劫舍2--dp+分治

与打家劫舍1不同的是它最后一个和第一个会相邻&#xff0c;事实上&#xff0c;从结果思考&#xff0c;最后只会有三种&#xff1a;1 第一家不被抢 最后一家被抢 2 第一家被抢 最后一家不被抢 3 第一和最后一家都不被抢 。那么&#xff0c;根据打家劫舍1中的算法 我们能算出在i…

Vmware虚拟机瘦身及Samba服务不可用问题解决

虚拟机磁盘空间膨胀是一个令人头疼的问题&#xff0c;特别是对许多搞开发的小伙伴。无论是做后台服务、嵌入式还是Android开发&#xff0c;都面临着这个难题。首先&#xff0c;操作系统本身就已占用不少空间&#xff0c;更新安装包&#xff0c;再下载一些开源软件&#xff0c;剩…

解码Starknet Verifier:深入逆向工程之旅

1. 引言 Sandstorm为&#xff1a; 能提交独立proof给StarkWare的Ethereum Verifier&#xff0c;的首个开源的STARK prover。 开源代码见&#xff1a; https://github.com/andrewmilson/sandstorm&#xff08;Rust&#xff09; L2Beat 提供了以太坊上Starknet的合约架构图&…

Docker私有仓库搭建

下载离线镜像 检查Docker环境 docker versionDocker Hub 中registry 最新版本为 2.8.3&#xff0c;详见 registry . https://hub.docker.com/_/registry/tags 下载镜像 docker pull registry:2.8.3离线导出&#xff0c;方便在无法联网的设备上安装 docker image save regi…

【QT学习】12.UDP协议,广播,组播

一。Udp详细解释 UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接的传输层协议&#xff0c;它提供了一种简单的、不可靠的数据传输服务。与TCP相比&#xff0c;UDP不提供可靠性、流量控制、拥塞控制和错误恢复等功能&#xff0c;但由于其简单性和低开销&#x…

单片机编程实例400例大全(100-200)

今天继续分享单片机编程实例第100-200例。 今天的实例会比前面100复杂一些&#xff0c;我大概看了下&#xff0c;很多都具备实际产品的参考价值。 今天继续分享单片机编程实例第100-200例。 今天的实例会比前面100复杂一些&#xff0c;我大概看了下&#xff0c;很多都具备实际…

【Java】HOT100 贪心算法

目录 理论基础 一、简单贪心 LeetCode455&#xff1a;分发饼干 二、中等贪心 2.1 序列问题 LeetCode376&#xff1a;摆动序列 2.2 贪心股票问题 LeetCode121&#xff1a;买卖股票的最佳时机 LeetCode121&#xff1a;买卖股票的最佳时机ii 2.3 两个维度权衡问题 LeetCode135&…

GPT是什么?直观解释Transformer | 深度学习第5章 【3Blue1Brown 官方双语】

【官方双语】GPT是什么&#xff1f;直观解释Transformer | 深度学习第5章 0:00 - 预测&#xff0c;采样&#xff0c;重复&#xff1a;预训练/生成式/Transformer模型 3:03 - Transformer 的内部结构 6:36 - 本期总述 7:20 - 深度学习的大框架 12:27 - GPT的第一层&#xff1a;…

NIO(非阻塞I/O)和IO(阻塞I/O)详解

文章目录 一、NIO&#xff08;Non-blocking I/O&#xff0c;非阻塞I/O&#xff09;1、Channel&#xff08;通道&#xff09;与Buffer&#xff08;缓冲区&#xff09;1.1、使用ByteBuffer读取文件1.2、ByteBuffer 方法1.2、ByteBuffer 结构1.3、字符串与 ByteBuffer 互转1.4 Sca…

Github查找代码项目高级语法(含科研项目查找案例)

基础搜索语法 1.搜索名字 in:name XXX 2.搜索描述 in:description XXX 3.搜索readme in:readme XXX 4.根据stars stars:>2000 5.根据fork fork:>3000 6.仓库大小搜索 size:>5000 [注意: 该处单位大小为 k] 7.根据更新时间 …

Spark01 —— Spark基础

文章目录 Spark01 —— Spark基础一、为什么选择Spark&#xff1f;1.1 MapReduce编程模型的局限性1.2 Spark与MR的区别1.3 版本1.4 优势1.5 Spark其他知识1、多种运行模式2、技术栈3、spark-shell&#xff1a;Spark自带的交互式工具4、Spark服务 二、Spark的基础配置三、Spark实…