【转】 memset()的效率以及源码分析
void *memset(void *s, int ch, size_t n);
作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
不知道有没有像我一样把memset当作万能的初始化工具,例如:
int arr[n];
memset(arr,1,n*sizeof(int));
这样得到的arr数组一定不是全0,而是16843009,下面解释原因。
首先,变量类型的本质只是标志从某一内存地址开始读取的位数,强制转换就是改变读取位数的大小。
下面来看memset的实现:(代码来自《C标准库》P398)
- void *(memset) (void *s,int c,size_t n)
- {
- const unsigned char uc = c;
- unsigned char *su;
- for(su = s;0 < n;++su,--n)
- *su = uc;
- return s;
- }
第3行把int类型的c转换成unsigned char类型,意味着截去c的高24位,只保留低8位。第4行把s当作unsigned char*类型,也就是说su中的每一个元素按8位计算。
现在来看看文章开头的那个代码会做什么。
c的二进制 : 00000000000000000000000000000001(32位)
1、c转换为unsigned char 后:00000001(8位)
2、将指针su(unsigned char类型)的每一元素(8位)赋值为00000001,循环4n次。
3、memset()结束后,arr的每个元素按照int类型读取,读出来的就是1000000010000000100000001,十进制就是16843009。
不过如果是memset(arr,0,n*sizeof(int));的话可以使用,因为32位都是0
再来说memset()的效率问题。使用memset函数与将上面的函数代码写在自己的程序里是不一样的,C标准库中的memset对Cache的利用做了优化,具体的在《C专家编程》151页有解释(其实是我没看懂),这里给出测试:
- #include <string.h>
- #define MAXSIZE 100000
- int main()
- {
- char arr[MAXSIZE];
- for(int i=0;i<10000;i++)
- {
- memset(arr,'0',sizeof(arr));
- // for(int j=0;j<MAXSIZE;j++)
- // arr[0] = '0';
- }
- return 0;
- }
程序里的注释部分与memset行分别使用,结果是使用memset的程序运行时间大约为0.1s,而用for循环的程序要3s多。
综上:memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动赋值要高的多。
转:http://blog.csdn.net/hackbuteer1/article/details/7343189
【转】 memset()的效率以及源码分析的更多相关文章
- Envoy 源码分析--network
目录 Envoy 源码分析--network address Instance DNS cidr socket Option Socket ListenSocket ConnectionSocket ...
- 一步步实现windows版ijkplayer系列文章之三——Ijkplayer播放器源码分析之音视频输出——音频篇
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- string源码分析 ——转载 http://blogs.360.cn/360cloud/2012/11/26/linux-gcc-stl-string-in-depth/
1. 问题提出 最近在我们的项目当中,出现了两次与使用string相关的问题. 1.1. 问题1:新代码引入的Bug 前一段时间有一个老项目来一个新需求,我们新增了一些代码逻辑来处理这个新需求.测试阶 ...
- Epoll详解及源码分析【转】
转自:http://blog.csdn.net/chen19870707/article/details/42525887 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...
- Nginx源码分析:3张图看懂启动及进程工作原理
编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」. 导读:很多工程师及架构师都希望了解及掌握高性能服务器 ...
- winafl 源码分析
前言 winafl 是 afl 在 windows 的移植版, winafl 使用 dynamorio 来统计代码覆盖率,并且使用共享内存的方式让 fuzzer 知道每个测试样本的覆盖率信息.本文主要 ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- JDK1.8 HashMap 源码分析
一.概述 以键值对的形式存储,是基于Map接口的实现,可以接收null的键值,不保证有序(比如插入顺序),存储着Entry(hash, key, value, next)对象. 二.示例 public ...
- cstore_fdw的安装使用以及源码分析
一.cstore_fdw的简介 https://github.com/citusdata/cstore_fdw,此外部表扩展是由citusdata公司开发,使用RC_file格式对数据进行列式存储. ...
随机推荐
- Difference between Stored Procedure and Function in SQL Server
Stored Procedures are pre-compile objects which are compiled for first time and its compiled format ...
- sms-provider
@ 最近测试 open-falcon. @ 首先得准备报警接口. sms-provider 邮件发送http接口: method: post params: content: 邮件内容 subject ...
- cocos2dx 3.x(在Mac平台下利用Eclipse打包安卓apk安装包详细教程)
最近在学习cocos2dx在MAC上如何打包apk,今天先把安装JDK和ANT的过程记来. 首先,打开终端,输入"java -version" 点击回车后,出现如下提示: 我们的M ...
- ios - 纯代码创建collectionView
开始考虑好一点点时间,因为一般的都是用xib,或者storyboard来写的.这次用纯代码...废话较多请看 首先把storyboard干掉,工程里面的main干掉 由于干掉了storyboard则启 ...
- lnmp环境下载安装包
一.下载php(官网):http://php.net/downloads.php 点击上图选择的php-7.0.10.tar.gz (sig) 进入如下页面: 需要在linux上面下载需要如下操作: ...
- 学习OpenCV——行人检测&人脸检测(总算运行出来了)
之前运行haar特征的adaboost算法人脸检测一直出错,加上今天的HOG&SVM行人检测程序,一直报错. 今天总算发现自己犯了多么白痴的错误——是因为外部依赖项lib文件没有添加完整,想一 ...
- 实时显示内容(Thread+Handler)
class LocThread extends Thread{ @Override public void run() { while (true){ try { Thread.sleep(99); ...
- 将n*n矩阵顺时针旋转90度
/** * 将n*n矩阵顺时针旋转90度 * @param mat * @param n 矩阵的阶数 * @date 2016-10-7 * @author shaobn */ public stat ...
- android cocos2d-x for Android安装和学习笔记(请用adt-bundle21.1或以上导入)
引用:http://weimingtom.iteye.com/blog/1483566 (20121108)注意:这篇文章用cdt编译ndk工程的内容已过时(现在可以用adt-bundle,避免配置繁 ...
- 让keepalived监控NginX的状态
经过前面的配置,如果主服务器的keepalived停止服务,从服务器会自动接管VIP对外服务:一旦主服务器的keepalived恢复,会重新接管VIP. 但这并不是我们需要的,我们需要的是当NginX ...