转自:老生常谈,正确使用memset

本文归纳了下使用memset几个需要注意的地方,虽然内容很简单,但也希望对大家有所帮助。

1. memset是以字节为单位,初始化内存块。
当初始化一个字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值,比如:
char data[10];
memset(data, 1, sizeof(data));    // right
memset(data, 0, sizeof(data));    // right  

而在初始化其他基础类型时,则需要注意,比如:

int data[10];
memset(data, 0, sizeof(data));     // right
memset(data, -1, sizeof(data));    // right
memset(data, 1, sizeof(data));     // wrong, data[x] would be 0x0101 instead of 1  
比如:
float (*p)[40]=new float[100][40];
memset(p,1,100*40);

因为memset是以字节为单位进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个float元素是4字节,合一起就是00000001000000010000000100000001,转换成十进制明显不是我们想要的结果。而3是没有把所有的内存全部清空。
所以用memset对非字符型数组赋初值是不可取的!清空内存却可以做到。
2. 当结构体类型中包含指针时,在使用memset初始化时需要小心。
比如如下代码:
struct Parameters {  int x;  int* p_x;
};
Parameters par;
par.p_x = new int[10];
memset(&par, 0, sizeof(par)); 

当memset初始化时,并不会初始化p_x指向的int数组单元的值,而会把已经分配过内存的p_x指针本身设置为0,造成内存泄漏。同理,对std::vector等数据类型,显而易见也是不应该使用memset来初始化的。

3. 当结构体或类的本身或其基类中存在虚函数时,也需要谨慎使用memset。
这个问题就是在开头项目中发现的问题,如下代码中,
class BaseParameters
{
public:  virtual void reset() {}
};  class MyParameters : public BaseParameters
{
public:   int data[3];  int buf[3];
};  MyParameters my_pars;
memset(&my_pars, 0, sizeof(my_pars));
BaseParameters* pars = &my_pars;  //......  MyParameters* my = dynamic_cast<MyParameters*>(pars);  

程序运行到dynamic_cast时发生异常。原因其实也很容易发现,我们的目的是为了初始化数据结构MyParameters里的data和buf,正常来说需要初始化的内存空间是sizeof(int) * 3 * 2 = 24字节,但是使用memset直接初始化MyParameters类型的数据结构时,sizeof(my_pars)却是28字节,因为为了实现多态机制,C++对有虚函数的对象会包含一个指向虚函数表(V-Table)的指针,当使用memset时,会把该虚函数表的指针也初始化为0,而dynamic_cast也使用RTTI技术,运行时会使用到V-Table,可此时由于与V-Table的链接已经被破坏,导致程序发生异常。

C语言之memset函数的使用相关推荐

  1. 【转】C语言的memset函数

    http://vip.6to23.com/tenax/clib/string/memset.htmlhttp://hi.baidu.com/longchengjiang/blog/item/32c0e ...

  2. 【C语言】memset函数用法

    数组也可以直接进行初始化,但 memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的. 头文件:#include <string.h> void *me ...

  3. c++ memset 语言_C++ memset函数

    [转载于https://www.cnblogs.com/yhlboke-1992/p/9292877.html] memset 函数是内存赋值函数,用来给某一块内存空间进行赋值的: 包含在头文件中,可 ...

  4. C语言之memset函数

    [FROM MSDN && 百科] 原型:  void *memset(void *s,int ch,size_t n); #include<string.h> 将 s 中 ...

  5. 编写一个自己的完全C语言版本的memset函数,并且评价这个实现的性能和可移植性。

    编写一个自己的完全C语言版本的memset函数,并且评价这个实现的性能和可移植性. memset这个函数的作用大致可以理解为将从指针指向的地址开始的指定字节长度的空间全部替换为指定的值.那么我们可以很 ...

  6. c++ memset 语言_C/C++ 中memset() 函数详解及其作用介绍

    memset 函数是内存赋值函数,用来给某一块内存空间进行赋值的: 包含在头文件中,可以用它对一片内存空间逐字节进行初始化: 原型为 : void *memset(void *s, int v, si ...

  7. c语言memset函数用法,C语言memset函数使用方法详解

    C语言memset函数使用方法详解 一.函数原形   void *  memset(void*s, int ch,size_t n) 二.函数作用  将以s内存地址为首的连续n个字节的内容置成ch,一 ...

  8. C语言memset函数

    C语言memset函数 一.memset函数是什么有什么作用 二.为什么使用menset函数 三.memset函数的使用 一.memset函数是什么有什么作用 # include <string ...

  9. c语言memset对应java,C语言memset函数详解

    C语言memset函数详解 memset() 的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零. 它是直接操作内存空间,mem即"内存"(memory)的意思. ...

最新文章

  1. 软件工程网络15结对编程作业
  2. WebGIS--ArcGIS for Flex系列开发一:flash builder
  3. MYSQL 密码相关记录
  4. WordPress插件扫描工具plecost
  5. PyTorch 实现经典模型4:GoogLeNet
  6. IT行业的日常工作方法 学习(转)
  7. ansole终端链接linux,基于Linux系统的智能家居远程控制系统设计论文.doc
  8. webservice用cxf发布SOAP
  9. 使用dynDNS+openSSH+putty突破公司防火墙
  10. html的table弹窗_Js弹出基于Table的可关闭浮动层
  11. jQuery attributes(上)
  12. 计算机导论知识点整理笔记(一.数据结构)
  13. 从没有C到ANSI C的认识
  14. zabbix自定义SNMP监控项
  15. 项目管理沙龙第二次聚会纪要
  16. Android MQTT客户端
  17. 乡镇政府网络智能办公系统(乡镇OA)应用【乡镇信息化经验】
  18. 路在脚下,梦就在前方
  19. Java8 Phaser 源码解析
  20. 网站死链检查处理方法

热门文章

  1. GB18030与GBK、GB2312字节对照
  2. ZRender使用中关于图片裁剪、拖拽问题
  3. caffe2的安装与遇到的问题和解决问题步骤
  4. 恺撒密码(Python练习)
  5. 计算机组装与维护的感想心得,选修计算机组装与维护学习心得
  6. SyntaxError: Non-UTF-8 code starting with ‘\xb3‘ in file解决方案
  7. 南华大学计算机科学学院,湖南科技大学计算机科学与工程学院前来南华大学计算机学院进行访问与交流...
  8. go语言:环境变量GOPROXY和GO111MODULE设置
  9. Pop!_Os使用手册
  10. 人民币金额中数字格式转化为中文的人民币大写格式的全部代码