目录
- 写在前面
- 指针和内存管理
- 正常使用
- 类型转换中的使用
- 分割内存块建立链接
- 新知识收获
- (void *)0和null
- (void*)和 *
写在前面
- 关于指针的内容,在本科的时候有学过,但是仅限于学过,使用起来那是跟没学过一样,最近读操作系统源码和师兄写的代码有点头秃,特此总结一下。
指针和内存管理
- 内存分配和释放:操作系统使用指针来管理系统的内存资源。通过指针,可以动态地分配和释放内存空间,以满足不同程序的内存需求。常见的内存分配函数如malloc()和free()就是通过指针来进行内存管理的。
- 数据结构的构建和操作:指针在数据结构中的应用非常广泛。通过指针,可以创建和操作复杂的数据结构,如链表、树、图等。指针可以用于连接不同的节点或元素,实现数据的动态组织和访问。
- 函数传参:指针可以作为函数的参数传递,用于在函数之间传递大块的数据或者在函数内部修改外部变量的值。通过传递指针,可以避免数据的复制,提高程序的效率。
- 内存拷贝和移动:指针可以用于内存的拷贝和移动操作。通过指针,可以直接访问和操作内存中的数据,实现数据的复制、移动和重排等操作。
- 虚拟内存管理:操作系统使用指针来管理虚拟内存。虚拟内存是一种将物理内存和磁盘空间结合起来使用的技术。通过指针,操作系统可以将虚拟地址映射到物理地址,实现内存的动态分配和管理。指针在虚拟内存管理中起到了关键的作用。
- 进程间内存共享:指针在进程间内存共享中也有应用。操作系统可以通过指针将内存区域映射到多个进程的地址空间中,实现进程间的内存共享。这种共享方式可以提高进程间的通信效率和数据共享的灵活性。
- 内存保护和权限管理:指针在内存保护和权限管理方面也有重要的应用。操作系统可以使用指针来管理内存的访问权限,限制进程对特定内存区域的访问。通过指针,操作系统可以实现内存的保护和隔离,提高系统的安全性和稳定性。
- 内存碎片整理:指针在内存碎片整理中也发挥着重要的作用。操作系统可以使用指针来重新组织和整理内存中的碎片,以提高内存的利用率和性能。通过指针,操作系统可以将多个小的内存块合并成一个大的内存块,减少内存碎片的产生。
总之,指针在操作系统的内存管理方面扮演着重要的角色。它们提供了灵活和高效的方式来管理和操作内存资源,使得操作系统能够更好地管理系统的内存,提高系统的性能和资源利用率。
正常使用
#include <stdio.h>
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;
}
类型转换中的使用
#include <stdio.h>
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的地址
}
分割内存块建立链接
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 * )类型,可以使其成为一个通用的指针,可以存储任意类型的指针值。
- 而* 是一个解引用操作符,用于访问指针所指向的内存地址处的值。当应用于指针时,* 可以获取指针所指向的值。