深入学习C语言中memset()函数的用法
头文件:
#include <string.h>
memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:
void * memset( void * ptr, int value, size_t num );
参数说明:
ptr 为要操作的内存的指针。
value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII 码相互转换。
num 为 ptr 的前 num 个字节,size_t 就是unsigned int。
【函数说明】memset() 会将 ptr 所指的内存区域的前 num 个字节的值都设置为 value,然后返回指向 ptr 的指针。
memset() 可以将一段内存空间全部设置为特定的值,所以经常用来初始化字符数组。例如:
char str[20]; memset(str, '\0', sizeof(str)-1);
【返回值】返回指向 ptr 的指针。
注意:参数 value 虽声明为 int,但必须是 unsigned char,所以范围在0 到255 之间。
范例:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { // 不可以声明为 char *str = "http://c.biancheng.net"; char str[] = "http://c.biancheng.net"; memset(str, '-', 7); puts(str); system("pause"); return EXIT_SUCCESS; }
执行结果:
-------c.biancheng.net
优化:尽量用memset将一个数组设置清零(带虚类除外),而不是通过for循环逐个置0
下面这个例子,大家可以参考:3D游戏编程大师技巧。本文其实重点是memset,原因是在工作中,用的比较多。
例如:要清空一个float f[10000],应该用memset(f,0,sizeof(float) * 10000);
而不是: for(int i=0; i<10000; ++i) f[i] = 0;
当然,还可以用内嵌汇编的形式:
_asm { mov edi, f; // edi指向数组地的目标内存的起始处 mov ecx, 1000/4; // 循环次数或移动次数 mov eax, 0; // 每一次移动32位数,都置0 rep stosd; // 移动数据 }
哈,这个准则有个前提,那就是带虚的类除外,原因是,memset将类清空,有可能将虚表也给置0了。
有可能是因为:类的创建分:栈上和堆上。
如果在栈上,那么栈对象的虚函数调用可能会在静态时确定,从而绕过虚表。所以不会出错。
但堆上就一定会出错,下面给出测试代码:
class CMemsetVirtualTest // 测试 带虚类,被memset为0后,虚表是否失效 { public: CMemsetVirtualTest() { memset(this,0,sizeof(CMemsetVirtualTest)); } virtual void NormalFun() { cout<<"test: NormalFun() 虚表指针有效"<<endl; } virtual ~CMemsetVirtualTest() { cout<<"test: ~CMemsetVirtualTest() 虚表指针有效"<<endl; } }; void testFun1() // 测试:栈上建立的对象 { CMemsetVirtualTest Ctest; Ctest.NormalFun(); } void testFun2() // 测试:堆上建立的对象 { CMemsetVirtualTest* Ptest = new CMemsetVirtualTest(); Ptest->NormalFun(); // 到这里一定会暴掉 delete Ptest; // 如果屏蔽上句,到这里也一定会暴掉 } int main() { CMemsetVirtualTest Ctest;// 测试:栈上建立的对象 Ctest.NormalFun();// 测试正常: CMemsetVirtualTest* Ptest = new CMemsetVirtualTest(); // 测试:堆上建立的对象 Ptest->NormalFun(); // 到这里一定会暴掉 delete Ptest; // 如果屏蔽上句,到这里也一定会暴掉 }
即:
在C++中,涉及虚技术的类,他的对象内存区块中就不单纯是用户定义这个类时看上去的那些数据结构,编译器会在当中安插一些数据或代码,用来实现响应的虚技术.于是当你用memset函数时会把这些编译器安插的东西冲掉, 程序执行结果变得未知. 这时候如果拷贝对象C++会使用memberwise拷贝, 此时编译器既拷贝用户定义的数据结构,还会对支持虚技术的相关设施进行适当的修改.
如果对象没有用到虚技术, 那么就可以使用memset,就跟正常情况一样,可以逐位拷贝.
栏 目:C语言
本文地址:https://www.xiuzhanwang.com/a1/Cyuyan/2850.html
您可能感兴趣的文章
- 04-02c语言函数调用后清空内存 c语言调用函数删除字符
- 04-02c语言的正则匹配函数 c语言正则表达式函数库
- 04-02func函数+在C语言 func函数在c语言中
- 04-02c语言中对数函数的表达式 c语言中对数怎么表达
- 04-02c语言用函数写分段 用c语言表示分段函数
- 04-02c语言编写函数冒泡排序 c语言冒泡排序法函数
- 04-02c语言没有round函数 round c语言
- 04-02c语言分段函数怎么求 用c语言求分段函数
- 04-02C语言中怎么打出三角函数 c语言中怎么打出三角函数的值
- 04-02c语言调用函数求fibo C语言调用函数求阶乘
阅读排行
本栏相关
- 04-02c语言函数调用后清空内存 c语言调用
- 04-02func函数+在C语言 func函数在c语言中
- 04-02c语言的正则匹配函数 c语言正则表达
- 04-02c语言用函数写分段 用c语言表示分段
- 04-02c语言中对数函数的表达式 c语言中对
- 04-02c语言编写函数冒泡排序 c语言冒泡排
- 04-02c语言没有round函数 round c语言
- 04-02c语言分段函数怎么求 用c语言求分段
- 04-02C语言中怎么打出三角函数 c语言中怎
- 04-02c语言调用函数求fibo C语言调用函数求
随机阅读
- 01-10SublimeText编译C开发环境设置
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 04-02jquery与jsp,用jquery
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 01-11ajax实现页面的局部加载
- 01-10delphi制作wav文件的方法
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-10C#中split用法实例总结