内存管理中的一级指针和二级指针

目录

  • 写在前面
  • 指针和内存管理
    • 正常使用
    • 类型转换中的使用
    • 分割内存块建立链接
  • 新知识收获
    • (void *)0和null
    • (void*)和 *

写在前面

  • 关于指针的内容,在本科的时候有学过,但是仅限于学过,使用起来那是跟没学过一样,最近读操作系统源码和师兄写的代码有点头秃,特此总结一下。

指针和内存管理

  • 内存分配和释放:操作系统使用指针来管理系统的内存资源。通过指针,可以动态地分配和释放内存空间,以满足不同程序的内存需求。常见的内存分配函数如malloc()和free()就是通过指针来进行内存管理的
  • 数据结构的构建和操作:指针在数据结构中的应用非常广泛。通过指针,可以创建和操作复杂的数据结构,如链表、树、图等。指针可以用于连接不同的节点或元素,实现数据的动态组织和访问。
  • 函数传参:指针可以作为函数的参数传递,用于在函数之间传递大块的数据或者在函数内部修改外部变量的值。通过传递指针,可以避免数据的复制,提高程序的效率。
  • 内存拷贝和移动:指针可以用于内存的拷贝和移动操作。通过指针,可以直接访问和操作内存中的数据,实现数据的复制、移动和重排等操作。
  • 虚拟内存管理:操作系统使用指针来管理虚拟内存。虚拟内存是一种将物理内存和磁盘空间结合起来使用的技术。通过指针,操作系统可以将虚拟地址映射到物理地址,实现内存的动态分配和管理。指针在虚拟内存管理中起到了关键的作用。
  • 进程间内存共享:指针在进程间内存共享中也有应用。操作系统可以通过指针将内存区域映射到多个进程的地址空间中,实现进程间的内存共享。这种共享方式可以提高进程间的通信效率和数据共享的灵活性。
  • 内存保护和权限管理:指针在内存保护和权限管理方面也有重要的应用。操作系统可以使用指针来管理内存的访问权限,限制进程对特定内存区域的访问。通过指针,操作系统可以实现内存的保护和隔离,提高系统的安全性和稳定性。
  • 内存碎片整理:指针在内存碎片整理中也发挥着重要的作用。操作系统可以使用指针来重新组织和整理内存中的碎片,以提高内存的利用率和性能。通过指针,操作系统可以将多个小的内存块合并成一个大的内存块,减少内存碎片的产生。

总之,指针在操作系统的内存管理方面扮演着重要的角色。它们提供了灵活和高效的方式来管理和操作内存资源,使得操作系统能够更好地管理系统的内存,提高系统的性能和资源利用率。

正常使用

#include <stdio.h>

int main() {
    int num = 10;
    int *ptr = &num;    //一级指针ptr,指向num的地址
    int **pptr = &ptr;  //二级指针pptr,指向ptr的地址 

    printf("num的值:%d\n", num);
    
    printf("ptr的值:%d\n", ptr);
    printf("*pptr的值:%d\n", *pptr);
    
    printf("*ptr的值:%d\n", *ptr);
    printf("**pptr的值:%d\n", **pptr);

    *ptr = 20;  		//通过一级指针修改num的值
    printf("修改后的num的值:%d\n", num);
	
	**pptr = 30;		//通过二级指针修改num的值 
	printf("修改后的num的值:%d\n", num);
	
    return 0;
}

在这里插入图片描述

类型转换中的使用

#include <stdio.h>

int main() {
    int num = 10;
    int *ptr = &num;     //一级指针ptr,指向num的地址
    int **pptr = &ptr;   //二级指针pptr,指向ptr的地址 
    
    //下面这三个值一样,类型转换不改变值 
	printf("%d\n",ptr); //num的地址
	printf("%d\n",(int*)ptr);
    printf("%d\n",(int**)ptr);
    
    printf("%d\n",*ptr);
    printf("%d\n",*(int*)ptr);
    printf("%d\n",*(int**)ptr);
	 
    printf("%d\n",pptr);//ptr的地址  
}

在这里插入图片描述

分割内存块建立链接

X_OS_MEM  *MemCreate (void  *addr,  X_INT32U  nblks, X_INT32U  blksize)
{
	//不知道为什么师兄的代码里面没有malloc在tornado上居然也可以运行,可能是tornado太老了
	X_OS_MEM     *pmem = (X_OS_MEM*)malloc(sizeof(X_OS_MEM));						
    X_INT8U      *pblk;						 
    void         **plink;					 ,
    X_INT32U     loops;
    X_INT32U     i;
//***********************************************************************************在下面		
	plink = (void **)addr;  				                       
    pblk  = (X_INT8U *)addr;				
    
    loops  = nblks - 1u;
    for (i = 0u; i < loops; i++) {       
        pblk +=  blksize;  				                                      
        *plink = (void  *)pblk;                       
        plink = (void **)pblk;                       
    }
//***********************************************************************************在上面    
    pmem->OSMemAddr     = addr;  
    pmem->OSMemEndAddr  = (void *)plink + blksize;      
    pmem->OSMemFreeList = addr;                       
    pmem->OSMemNFree    = nblks;                      
    pmem->OSMemNBlks    = nblks;
    pmem->OSMemBlkSize  = blksize;  
    *plink              = (void *)0;        			 
	return (pmem);
}
  • plink 是addr的所表示的地址值
  • pblk 也是addr的所表示的地址值,X_INT8U类型是为了下面做加法以跳到下一个内存块的起始地址
    在这里插入图片描述

新知识收获

(void *)0和null

  • 在C语言中,(void *)0和NULL在表示空指针的意义上是等价的。它们都表示一个空指针常量用于表示指针的空值或者内存分配失败的情况
  • 在实际使用中,我们可以使用任意一种形式来表示空指针,它们的含义是相同的。通常情况下,建议使用NULL来表示空指针,因为它是C语言标准库中定义的宏,具有更好的可读性和可移植性。

(void*)和 *

  • (void * ) 是一种类型转换操作,将指针转换为 void 类型的指针。void 类型是一种特殊的类型,可以用来表示任意类型的指针。通过将指针转换为 (void * )类型,可以使其成为一个通用的指针,可以存储任意类型的指针值。
  • 而* 是一个解引用操作符,用于访问指针所指向的内存地址处的值。当应用于指针时,* 可以获取指针所指向的值。

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

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

相关文章

HashMap

JDK1.7: ArrayList 内部是数组结构 LinkeList内部是链表结构 TreeMap 是二叉树结构 HashMap 是数组链表 读取(put)慢 会读取所有的key 确定有没有重复,通过hash优化 Hash碰撞时两个不同的Key 取模时 得到了一样的key 通过链表进行存放 初始大小 1 << 4 ,16 ------和满载…

text/xml和application/xml

困惑 在http消息中&#xff0c;同样是传送xml信息&#xff0c;有的时候看到Content-Type的值是text/xml&#xff0c;有的时候值是application/xml&#xff0c;感到困惑。 例如&#xff0c;用Postman发送http消息给Tomcat中的基于JAX-WS的 web服务&#xff1a; 请求中传送了xm…

YOLOv8改进 | ICLR 2022 |ODConv附修改后的C2f、Bottleneck模块代码

论文地址&#xff1a;论文地址点击即可跳转阅读 代码地址&#xff1a;文末提供复制粘贴的代码块 一、本文介绍 这篇文章给大家带来的是发表于2022年ICLR的ODConv(Omni-Dimensional Dynamic Convolution)中文名字全维度动态卷积&#xff0c;该卷积可以即插即用&#xff0c;可…

Ubuntu22.04离线安装uwsgi问题记录

GCC4.8安装 1、报错信息1&#xff1a; 由于缺少gcc4.8环境导致的无法安装uwsgi 解决方案&#xff1a; 离线安装GCC4.8环境, GCC4.8.5离线安装步骤如下&#xff1a; 1、下载gcc的离线安装包及其依赖包&#xff0c;链接如下&#xff1a; https://download.csdn.net/download/…

苹果MAC安装绿盾出现问题,安装时没有出现填服务器地址的页面,现在更改不了也卸载不了绿盾 怎么处理?

环境: Mac mini M1 Mac os 11.0 绿盾v6.5 问题描述: 苹果MAC安装绿盾出现问题,安装时没有出现填服务器地址的页面,现在更改不了也卸载不了绿盾 怎么处理? 解决方案: 大部分企业是Windows和Mac终端混合使用,在进行文档加密管理时通常会遇到不兼容的现象,而为了统一…

Google codelab WebGPU入门教程源码<2> - 绘制几何形状(源码)

对应的教程文章: https://codelabs.developers.google.com/your-first-webgpu-app?hlzh-cn#3 源码执行效果: 对应的教程源码: 此处源码和教程本身提供的部分代码可能存在一点差异。 class Color4 {r: number;g: number;b: number;a: number;constructor(pr 1.0, pg 1.0, …

C++初阶 类和对象(下)

目录 一、拷贝构造函数 1.1 什么是拷贝构造函数&#xff1f; 1.2 为什么得是引用&#xff1f; 1.3 使用拷贝构造函数 1.4 拷贝构造函数有什么用&#xff1f; 二、运算符重载 2.1 什么是运算符重载&#xff1f; 2.2 尝试前须知 2.3 常见运算符重载 2.3.1运算符重载 …

树莓派通过网线连接电脑(校园网也能连接),实现SSH连接

前言 之前通过串口登入树莓派&#xff0c;太麻烦&#xff0c;通过网络登入树莓派&#xff0c;学校校园网又连接不了&#xff0c;想起来可以使用网线连接树莓派和电脑。 目录 树莓派通过网线连接电脑思路分析 树莓派通过网线连接电脑实现 1.硬件需求 2.打开Windows的网络 …

12.Oracle的索引

Oracle11g的索引 一、什么是索引二、索引的分类三、索引的语法四、分析索引四、索引的作用及使用场景 一、什么是索引 在Oracle数据库中&#xff0c;索引是一种特殊的数据结构&#xff0c;用于提高查询性能和加速数据检索。索引存储了表中某列的值和对应的行指针&#xff0c;这…

2023.11.15 关于 Spring Boot 配置文件

目录 引言 Spring Boot 配置文件 properties 配置文件说明 基本语法 读取配置文件 优点 缺点 yml 配置文件说明 基本语法 读取配置文件 yml 配置不同数据数据类型及 null 字符串 加单双引号的区别 yml 配置 列表&#xff08;List&#xff09; 和 映射&#xff08;…

WordPress丸子小程序问题常见解决方案

WordPress丸子小程序问题常见解决方案 下载uniapp&#xff0c;导入项目。修改下图域名为自己的WP博客地址。&#xff08;如下图&#xff09; 发行微信小程序&#xff0c;如果显示不是项目所有者&#xff0c;请重新获取。 重新发行微信小程序&#xff0c;请打开微信开发者工具端…

MySql分区

一、什么是分区 MySQL分区是一种数据库设计和管理技术&#xff0c;它允许你将表分割成独立的、具有特定规则的存储单元。每个分区可以独立地进行管理&#xff0c;包括备份、恢复和优化。分区的主要目的是提高查询性能、简化维护以及实现数据的更有效管理。 以下是MySQL分区的…

深度解析:ERP管理系统背后的逻辑

深度解析&#xff1a;ERP管理系统背后的逻辑企业运营日益复杂化&#xff0c;一套高效且实用的ERP管理系统成为了企业成功的关键因素之一。然而&#xff0c;许多企业对于ERP管理系统的理解仍停留在表面&#xff0c;并未深入理解其背后的逻辑。本文将为您深度解析ERP管理系统背后…

腾讯云服务器价格表查询,腾讯云服务器怎么买便宜?

你是否需要搭建一个属于自己的网站&#xff0c;但是又不知道该如何选择和购买服务器&#xff1f;腾讯云服务器价格表查询&#xff0c;让你轻松了解各款服务器的价格及配置信息&#xff0c;帮助你选择最合适的服务器。同时&#xff0c;我们还为你提供了腾讯云服务器的优惠购买入…

main.js 中的 render函数

按照之前的单组件文件中的写法&#xff0c;我们的写法应该是这样的 import App from ./App.vuenew Vue({el: #app,templete: <App></App>,components: {App}, }) 1、定义el根节点。2、注册App组件。3、渲染 templete 模板 但是在脚手架工程中&#xff0c;他是这…

kubernetes--数据存储

目录 一、数据存储引言&#xff1a; 二、基础存储卷&#xff1a; 1. emptyDir存储卷&#xff1a; 2. hostPath存储卷&#xff1a; 3. nfs共享存储卷&#xff1a; 3.1 配置nfs: 3.2 master节点编写yaml文件&#xff1a; 4. 总结&#xff1a; 三、PVC和PV&#xff1a; 1. PV 的…

Jmeter- Beanshell语法和常用内置对象(网络整理)

在利用jmeter进行接口测试或者性能测试的时候&#xff0c;我们需要处理一些复杂的请求&#xff0c;此时就需要利用beanshell脚本了&#xff0c;BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的。beans…

python趣味编程-5分钟实现一个测验应用程序(含源码、步骤讲解)

Python测验是用 Python 编程语言编写的,这个关于 Python 编程的简单测验是一个简单的项目,用于测试一个人在给定主题考试中的知识能力。 Python 中的 Quiz项目仅包含用户端。用户必须先登录或注册才能开始Python 测验。 此外,还规定了解决问题的时间。用户应在时间结束前解…

VIM去掉utf-8 bom头

Windows系统的txt文件在使用utf-8编码保存时会默认在文件开头插入三个不可见的字符&#xff08;0xEF 0xBB 0xBF&#xff09;称为BOM头 BOM头文件 0.加上BOM标记&#xff1a; :set bomb 1.查询当前UTF-8编码的文件是否有BOM标记&#xff1a; :set bomb? :set bomb? 2.BOM头:文…

C语言的动态内存管理

目录 一、malloc函数 二、free函数 三、calloc函数 四、realloc函数 五、realloc函数原地扩容和异地扩容测试 六、动态内存管理的注意事项 一、malloc函数 1.头文件&#xff1a;stdlib.h&#xff08;malloc.h&#xff09; 2.函数原型&#xff1a;void * malloc(size_t siz…