指针的本质2-void和void*及其应用在nginx中的应用
指针有两个属性:指向变量/对象的地址和长度。
编译器根据指针的类型从指针指向的地址向后寻址,
指针类型不同则寻址范围也不同,比如:
int*从指定地址向后寻找4字节作为变量的存储单元,
double*从指定地址向后寻找8字节作为变量的存储单元 ,
1.void指针是一种特别的指针
void *vp
//说它特别是因为它没有类型
//或者说这个类型不能判断出指向对象的长度
2.任何指针都可以赋值给void指针
type *p;
vp=p;
//不需转换
//只获得变量/对象地址而不获得大小
3.void指针赋值给其他类型的指针时都要进行转换
type *p=(type*)vp;
//转换类型也就是获得指向变量/对象大小
转:http://icoding.spaces.live.com/blog/cns!209684E38D520BA6!130.entry
4.void指针不能复引用
*vp//错误
因为void指针只知道,指向变量/对象的起始地址
而不知道指向变量/对象的大小(占几个字节)所以无法正确引用
5.ANSI下void指针不能参与指针运算,除非进行转换,GNU允许
(type*)vp++;
//vp==vp+sizeof(type)
深度详解:
如果指针p1和p2的类型相同,那么我们能直接在p1和p2间互相赋值;
如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。
例如:
float *p1;
int *p2;
p1 = p2;
其中p1 = p2语句会编译出错,提示“’=’ : cannot convert from ’int *’ to ’float *’”,必须改为:
p1 = (float *)p2;
而void *则不同,所有类型的指针都能直接赋值给他,无需进行强制类型转换:
void *p1;
int *p2;
p1 = p2;
void *必须强制类型转换才能赋给其他类型的指针。因为“无类型”能包容“有类型”,而“有类型”则不能包容“无类型”。
1.void
《C程序设计语言(第2版新版)》
2.void*
《C程序设计语言(第2版新版)》
《C语言入门经典(第四版)》
《21天学通C语言(第6版)》
如果函数的参数能是任意类型指针,那么应声明其参数为void *。
3.指针转换
《C程序设计语言(第2版新版)》
4.指针运算
《21天学通C语言(第6版)》
例子:直接给void*指针运算会报错--“void*:未知的大小”
可以将空指针强制转换即可: (unsigned char*)k=(unsigned char*)k+1;
按照ANSI(American National Standards Institute)标准,不能对void指针进行算法操作,即下列操作都是不合法的:
void * pvoid;
pvoid++; //ANSI:错误
pvoid += 1; //ANSI:错误
ANSI标准之所以这样认定,是因为他坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。例如:
int *pint;
pint++; //ANSI:正确
pint++的结果是使其增大sizeof(int)。
不过GNU则指定void *的算法操作和char *一致。GNU下的void *p++相当于char *p++ 也就是移动一个字节。
因此下列语句在GNU编译器中皆正确:
pvoid++; //GNU:正确
pvoid += 1; //GNU:正确
pvoid++的执行结果是其增大了1。
在实际的程式设计中,为迎合ANSI标准,并提高程式的可移植性,我们能这样编写实现同样功能的代码:
void * pvoid;
(char *)pvoid ++; //ANSI:正确;GNU:正确
(char *)pvoid += 1; //ANSI:错误;GNU:正确
[JOEY 评:此处尚有疑问,(char *) pvoid ++,VS2005编译无法通过,提示:“void *”:未知的大小。]
GNU和ANSI更有一些差别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。不过我们在真实设计时,还是应该尽可能地迎合ANSI标准。
5.Nginx源码中的用法
声明内存池的结构,是使用u_char *定义last和end指针
typedef struct {u_char *last;u_char *end;ngx_pool_t *next;
}ngx_pool_data_t;
初始化
ngx_pool_t *ngx_create_pool(size_t size)
{ngx_pool_t *p;p=(ngx_pool_t*)malloc(size);p->d.last=(u_char *)p+sizeof(ngx_pool_t);p->d.end=(u_char *)p+size;size = size - sizeof(ngx_pool_t);p->max =size;p->current = p;return p;
}
内存分配
void *palloc(ngx_pool_t *pool,size_t size)
{u_char *m;ngx_pool_t *p;if (size <= pool->max){p = pool->current;do{m = p->d.last;if ((size_t) (p->d.end - m) >= size) {(u_char *)p->d.last+=size;return m;}p = p->d.next;}while(p);
以上的正常的使用没问题的。
其实可以将u_char *定义last指针改为void*指针,但是如果在指针运算使用的时候不进行强制转换会报错。这个和前面的void * k直接运算是一样的问题。
代码做下修改即可:
do{m = p->d.last;if ((size_t) (p->d.end - m) >= size) {(u_char *)p->d.last+=size;return m;}p = p->d.next;}while(p);
注意:void*空指针运算这个问题在Linux下用gcc编译不报错
下图是Nginx内存池图:
参考:指针的本质1--u_char*指针在Nginx源码中的应用及原因
相关文章:
首次揭秘!大麦如何应对超大规模高性能选座抢票?
作者| 阿里文娱技术专家恒磊、高级开发工程师新钱出品 | AI科技大本营(ID:rgznai100)背景介绍随着现场娱乐行业的不断发展,各类演出层出不穷,越来越多的演出开启选座购票满足用 户的自主选座需求。大麦的选座不仅面向中小场馆类的…

华为交换机密码恢复
华为交换机密码恢复说明:以下方法将删除原有config文件,使设备恢复到出厂配置。在设备重启时按CtrlB进入BOOT MENU之后,Press Ctrl-B to enter Boot Menu... 5Password : 缺省为空,回车即可1. Download application file to flash…
nginx源码分析--内存对齐处理
1.nginx内存对齐主要是做2件事情: 1) 内存池的内存地址对齐; 2) 长度按照2的幂取整.因为前面结构体已经是对齐了,如果后面的内存池每一小块不是2的幂,那么后面的就不能对齐 2.通用内存对齐理论 内存对齐:数据项只能…

七喜携手AMD,摆脱英特尔“潜规则”
七喜携手AMD,摆脱英特尔“潜规则”<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />最近,在PC市场随着七喜董事副总裁毛骏飙揭发英特尔制定的潜规则,“游戏规则都是英特尔制定的,全…
半小时训练亿级规模知识图谱,亚马逊AI开源知识图谱嵌入表示框架DGL-KE
出品 | AI科技大本营(ID:rgznai100) 知识图谱 (Knowledge Graph)作为一个重要的技术,在近几年里被广泛运用在了信息检索,自然语言处理,以及推荐系统等各种领域。学习知识图谱的嵌入表示 &#x…

数组的各类排序
1 package sort;2 3 /**4 * 数组的各种排序操作5 * Created by liuwei on 16/3/6.6 */7 public class MSort {8 9 /**10 * 直接插入排序11 * 外层一个循环,从第2个元素开始(下标为1),遍历后面的所有元素12 * 内层一个循环,从当前位置position i 开始,每次…
Virtualbox安装使用注意
1.VirtualBox升级到4.3以后不能打开 提示创建 COM 对象失败 应用程序将被中断 解决方案:右键VirtualBox的桌面快捷方式,选择属性,选到兼容性选项卡,勾选“以兼容模式运行这个程序”,下拉框选择Windows Server 2008 …
机器学习项目模板:ML项目的6个基本步骤
来源 | DeepHub IMBA每个机器学习项目都有自己独特的形式。对于每个项目,都可以遵循一组预定义的步骤。尽管没有严格的流程,但是可以提出一个通用模板。准备问题不仅是机器学习,任何项目的第一步都是简单地定义当前的问题。您首先需要了解背景…

ib_logfile 在数据库中有何作用?
ib_logfile 在数据库中有何作用? ib_logfile0/ib_logfile1 文件在数据库中起什么作用? 如果被删除,对数据库有何影响? ----->>>>>>>>>>> 回复 #1 mugua_xinli 的帖子 用于存放InnoDB引擎的事…

Podfile 常见语法
source URL : 指定镜像仓库的源 platform : ios, 6.0 : 指定所支持系统和最低版本 inhibit_all_warnings! :屏蔽所有warning workspace 项目空间名: 指定项目空间名 xcodeproj 工程文件名:指定xcodeproj工程文件名 …

今天学完了ccna
通过10天的学习,终于学完了NA,但是会不会呢?还是个未知数,再就也一知半解的。觉得基础知识太差了,可是看书,又觉得太长了,太多了,晚上老是停电 白天啥也看不进去。热。还是静不下心&…
攀登数据科学家和数据工程师之间的隔墙
来源 | 数据派 THU机器学习的教育和研究重点往往集中在数据科学过程的模型构建、训练、测试和优化等方面。要使这些模型投入使用,需要一套工程专长和组织结构,对于其中的标准尚不存在。有一个架构可以指导数据科学和工程团队相互协作,从而将机…

js变量以及其作用域详解
2019独角兽企业重金招聘Python工程师标准>>> 一、变量的类型 Javascript和Java、C这些语言不同,它是一种无类型、弱检测的语言。它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变…
在A*寻路中使用二叉堆
在A*寻路中使用二叉堆 作者:Patrick Lester(2003年4月11日更新) 译者:Panic 2005年3月28日 译者序: 这一篇文章,是“A* Pathfinding for Beginners.”,也就是我翻译的另一篇文章A*寻路初探…
“Hey Siri” 背后的黑科技大揭秘!
作者 | Vishant Batta译者 | 苏本如,责编 | 伍杏玲出品 | CSDN(ID:CSDNnews)以下是译文: 如今苹果手机可随时检测并回答“Hey Siri”命令,有人可能会想,它是不是在随时记录我们的日常生活对话呢…

[ASP.NET4之旅]Circular file references are not allowed
将ASP.NET 2.0的项目升级到ASP.NET 4后,用VS2010编译站点,某些控件出现编译错误“Circular file references are not allowed”,比如: <% Control Language"C#"ClassName"NewsRight"%>解决方法…

IOS-XMPP
一、即时通讯技术简介 即时通讯技术(IM -- Instant Messaging)支持用户在线实时交谈。如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容有许多的IM系统,如AO…

libcurl使用
官网:http://curl.haxx.se/libcurl/c/libcurl-tutorial.html #curl-config --libs 得到 -lcurl #cc libcurl_test.c -o libcurl_test -lcurl 所有的例子:http://curl.haxx.se/libcurl/c/example.html 例子: /***********************…

RH5.4下samba共享配置实例(3)
一、基于用户名的访问控制实例: 王乾大哥写的比较详细了,我是跟着他的教程学习的,按照他的教程走一边; 要求如下: 1、创建一个公共的交换文件夹,所有人都可以写入删除,但不能删除修改其他人的文…

《评人工智能如何走向新阶段》后记(再续21)
346.中国抗疫十大黑科技(以人工智能为主力的黑科技) 摘自数邦客(2020.3.30发布) 负压救护车 人工智能机器人:如送餐机器人、消毒机器人、服务型机器人,及机器人呼叫等呼吸道病毒核配检测试剂盒…

nagios npc安装后状态为off的解决方法
1、检查ndo2db的进程是不是二个 nagios 16825 0.0 0.1 6784 396 ? Ss 19:05 0:00 /usr/local/nagios/bin/ndo2db -c /usr/l nagios 17032 0.0 0.3 6784 1268 ? S 19:09 0:00 /usr/local/nagios/bin/ndo2db -c 2、检查nagios.log日志看…
C语言extern关键字定义外部变量--Redis源码extern使用
在Redis2.8中有networking.c,这个文件没有networking.h networking.c首先引入redis.h这个头文件 #include "redis.h" 在redis.c一开始就声明了全局变量 /* Global vars */ struct redisServer server; networking.c的createClient函数 redisClient *cr…
深度学习面试必备的25个问题
作者 | Tomer Amit译者 | 弯月,编辑 | 屠敏出品 | CSDN(ID:CSDNnews)在本文中,我将分享有关深度学习的25个问题,希望能够帮助你为面试做好准备。1.为什么必须在神经网络中引入非线性?答…

一分钟了解阿里云产品:先知计划
一、 概述 阿里云发布了各种各样的产品,今天让我们一起来了解下阿里云先知计划吧。 什么是先知计划呢? 先知计划是一个帮助企业建立私有应急响应中心的平台(帮助企业收集漏洞信息)。企业加入先知计划后,可…

C语言的HashTable简单实现
原文地址:http://blog.csdn.net/zmxiangde_88/article/details/8025541 HashTable是在实际应用中很重要的一个结构,下面讨论一个简单的实现,虽然简单,但是该有的部分都还是有的。 一,访问接口 创建一个hashtable. h…
GitHub标星2000+,如何用30天啃完TensorFlow2.0?
作者 | 梁云1991来源 | Python与算法之美(ID:Python_Ai_Road)天下苦tensorflow久矣!尽管tensorflow2.0宣称已经为改善用户体验做出了巨大的改进,really easy to use,但大家学得并不轻松。tensorflow2.0官方文档和tenso…

【Struts2学习笔记(1)】Struts2中Action名称的搜索顺序和多个Action共享一个视图--全局result配置...
一、Action名称的搜索顺序 1.获得请求路径的URI,比如url是:http://server/struts2/path1/path2/path3/test.action 2.首先寻找namespace为/path1/path2/path3的package,假设不存在这个package则运行步骤3;假…
大话卷积神经网络CNN,小白也能看懂的深度学习算法教程,全程干货建议收藏!...
来源 | 程序员管小亮本文创作的主要目的,是对时下最火最流行的深度学习算法的基础知识做一个简介,作者看过许多教程,感觉对小白不是特别友好,尤其是在踩过好多坑之后,于是便有了写这篇文章的想法。由于文章较长&#x…
频繁分配释放内存导致的性能问题的分析--brk和mmap的实现
现象1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看,发现majflt每秒增量为0&…