xiaoguozi's Blog
Pay it forword - 我并不觉的自豪,我所尝试的事情都失败了······习惯原本生活的人不容易改变,就算现状很糟,他们也很难改变,在过程中,他们还是放弃了······他们一放弃,大家就都是输家······让爱传出去,很困难,也无法预料,人们需要更细心的观察别人,要随时注意才能保护别人,因为他们未必知道自己要什么·····

void *memset(void *s, int v, size_t n); 

英文释义如下:

Copies the value v (converted to type unsigned char) to the first n bytes pointed to by s; returns s.
 
这里s可以是数组名,也可以是指向某一内在空间的指针;v为要填充的值;n为要填充的字节数,通常为sizeof(s);

使用memset时要注意的是,memset是逐字节进行填充,所以s一般为char *型。对于其它类型的s,可以填充的值有两个,0和-1。这是因为计算机中用二进制补码表示数字,0和二进制补码为全0,-1的二进制补码为全1。如果要初始化为其它的值,可以用一个for循环,如:

for(int i=0;i<n;i++)s[i]=v;

memset某个结构(或其它的数据类型)在C语言中是很常见的代码,其目的是对结构(或其它的数据类型)进行初始化,通常都是将变量置为NULL或者0。在C++中,针对类对象除了用构造函数初始化对象外,也可以使用memset来进行初始化操作(确实有这种情况,不得已而为之,请大家不要把鸡蛋砸过来!)。但是一定要注意以下所说的这种情况:如果类包含虚拟函数,则不能用 memset 来初始化类对象。下面是一个例子:

class GraphicsObject{
protected:
  char *m_pcName;
  int    m_iId;
  //etc
public:
  virtual void Draw() {}
  virtual int Area() {}
  char* Name() { return m_pcName;}
};

class Circle: public GraphicsObject{
  void Draw() { /*draw something*/ }
  int Area() { /*calculate Area*/ }
};

void main()
{
  GraphicsObject *obj = new Circle; // 创建对象
  memset((void *)obj,NULL,sizeof(Circle)); // memset to 0
  obj->Name(); // 非虚函数调用没问题
  obj->Draw(); // 在这里死得很难看
}

结果我就不说了。因为每个包含虚函数的类对象都有一个指针指向虚函数表(vtbl)。这个指针被用于解决运行时以及动态类型强制转换时虚函数的调用问题。该指针是被隐藏的,对程序员来说,这个指针也是不可存取的。当进行memset操作时,这个指针的值也要被overwrite,这样一来,只要一调用虚函数,程序便崩溃。这在很多由C转向C++的程序员来说,很容易犯这个错误,而且这个错误很难查。
为了避免这种情况,记住对于有虚拟函数的类对象,决不能使用 memset 来进行初始化操作。而是要用缺省的构造函数或其它的 init 例程来初始化成员变量。
posted on 2007-12-10 22:56 小果子 阅读(1884) 评论(4)  编辑 收藏 引用 所属分类: 学习笔记

FeedBack:
# re: memset使用注意
2008-08-20 19:43 | 哈哈
写的不错 鼓励鼓励  回复  更多评论
  
# re: memset使用注意
2008-08-20 21:10 | 沈臻豪(foxtail)
一般类最好不要这么干 天知道会发生什么  回复  更多评论
  
# re: memset使用注意
2008-09-03 17:02 | 小果子
@哈哈
上面我是摘录平时看到的,不过我遇到过用memset比这还让我头痛的..
上面其实知道虚函数的原理就不会memset了,我遇到的是不能对类中
有构造函数的或类成员中有类有构造函数的用memset,否则会出错..具体的看我写了一篇...
http://www.cppblog.com/guojingjia2006/archive/2008/08/15/58942.html  回复  更多评论
  
# re: memset使用注意
2009-06-21 12:26 | kikoqiu
ZeroMemory
大G博客挺干净的,夸一个  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理