C++ - memset的效率和源码分析

简介: void *memset(void *s, int ch, size_t n); 作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
 
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));的情况,效率比手动赋值要高的多。
 
目录
相关文章
|
C语言 C++
【C++从0到王者】第十五站:list源码分析及手把手教你写一个list(下)
【C++从0到王者】第十五站:list源码分析及手把手教你写一个list
84 0
|
存储 编译器 C语言
【C++从0到王者】第十五站:list源码分析及手把手教你写一个list(上)
【C++从0到王者】第十五站:list源码分析及手把手教你写一个list
74 0
|
编译器 Linux 测试技术
【C++从0到王者】第十三站:vector源码分析及手把手教你如何写一个简单的vector
【C++从0到王者】第十三站:vector源码分析及手把手教你如何写一个简单的vector
211 0
|
运维 监控 C语言
C++学习------cfenv头文件的作用与源码分析
cfenv是C++对C语言头文件fenv.h的封装,该头文件定义了一系列与浮点数运算环境相关的函数和宏定义,以及一些相关的结构体定义。它的作用主要是控制程序运行过程中浮点数运算的状态flag和控制模式,接下来我们来看看这个头文件的具体作用与实现原理。
562 0
C++学习——memset函数详解
C++学习——memset函数详解
294 0
Qt Creator plugin动手实践(4)C++ 类ModeManager源码分析
Qt Creator plugin动手实践(4)C++ 类ModeManager源码分析
319 0
Qt Creator plugin动手实践(4)C++ 类ModeManager源码分析
|
IDE 开发工具 C++
Qt Creator plugin动手实践(3)C++ 类ModeManager源码分析
Qt Creator plugin动手实践(3)C++ 类ModeManager源码分析
320 0
Qt Creator plugin动手实践(3)C++ 类ModeManager源码分析
|
C++
C++中,类如果包含map/list等对象,慎用memset(0)
C++中,类如果包含map/list等对象,慎用memset(0)
138 0
|
安全 C++
c++对象初始化中 ZeroMemory、memset、直接赋0的区别
首先是ZeroMemory和memset的区别: 1、ZeroMemory是微软的SDK提供的,memset属于C Run-time  Library提供的。因此ZeroMemory只能用于Windows系统,而memset还可用于其他系统。
1217 0