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

目录

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

写在前面

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

指针和内存管理

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

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

正常使用

#include 

int main() {
    int num = 10;
    int *ptr = #    //一级指针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;
}

内存管理中的一级指针和二级指针_第1张图片

类型转换中的使用

#include 

int main() {
    int num = 10;
    int *ptr = #     //一级指针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的地址  
}

内存管理中的一级指针和二级指针_第2张图片

分割内存块建立链接

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类型是为了下面做加法以跳到下一个内存块的起始地址
    内存管理中的一级指针和二级指针_第3张图片

新知识收获

(void *)0和null

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

(void*)和 *

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

你可能感兴趣的:(μC/OS-II学习,c语言,操作系统,内存管理)