前项目发现一个问题,计划永远是一个dynamic_cast当一个异常动态转换,搜索了半天才发现问题竟然是在memset使用,见。但当处于几十万行代码量级中时,就变得不太那么easy定位了。

本文归纳了下使用memset几个须要注意的地方,尽管内容非常easy。但也希望对大家有所帮助。

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
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时发生异常。

原因事实上也非常easy发现,我们的目的是为了初始化数据结构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该链接已被摧毁,导致程序异常。


陈词滥调,正确使用memset的更多相关文章

  1. 正确使用memset

    今天做了一道素数打表的题我在使用一个数组记录是否为素数的时候使用了memset,将数组里面的数都清为1,代表是素数,不是素数,就改成0,我在判断这一个数是否为素数是依据也是是0还是1,结果一直存在问题 ...

  2. 老生常谈,正确使用memset

    转自:http://blog.csdn.net/my_business/article/details/40537653 前段项目中发现一个问题,程序总是在某个dynamic_cast进行动态转换时出 ...

  3. 关于memset的几个易错点

    memset(void *s,int ch,size_t n); 作用:将s中当前位置后面的n个字节用 ch 替换并返回 s 注意这里是“字节”而非单位长度,memset不会考虑各个类型的单位长度,只 ...

  4. C 文件读写1

    打开文件 fopen( ) 函数来创建或者打开文件,这个调用会初始化一个FILE 类型的对象. 原型 FILE *fopen( const char * filename, const char * ...

  5. [转]《深度探索C++对象模型》读书笔记[一]

    前 言 Stanley B.Lippman1.   任何对象模型都需要的三种转换风味: ü        与编译器息息相关的转换 ü        语言语义转换 ü        程序代码和对象模型的 ...

  6. c语言学习目标

    运行c语言环境codeblocks. codeblocks的安装: 安装地址:http://www.codeblocks.org/downloads/26 codeblocks-16.01mingw- ...

  7. linux中memset的正确用法

    linux中memset的正确用法 [起因]希望对各种类型的数组进行初始化,避免野值 [函数头文件] 提示:在linux中可以在terminal中输入 "man memset"进行 ...

  8. 如何在多线程leader-follower模式下正确的使用boost::asio。

    #include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...

  9. 字符串数组初始化0 与memset 0 效率的分析

    转自:http://www.xuebuyuan.com/1722207.html 结合http://blog.sina.com.cn/s/blog_59d470310100gov8.html来看. 最 ...

随机推荐

  1. string和byte[]的转换 (C#)

    原文 string和byte[]的转换 (C#) string类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes  ...

  2. JS firebug小技巧

    实际上前端的发展与进步也离不开浏览器的支持,而对于开发者来讲,浏览器最好的支持,就是对于debug的良好支持,甚至在某些兴许接手的项目中,前端的debug甚至能够解决好多问题--不说了,都是泪啊!还是 ...

  3. android5.0(Lollipop) BLE Central牛刀小试

    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46482073 昨天写了android L BLE Peripheral的简单 ...

  4. VC2008下使用OpenSSL 1.0.0g(免编译)

    OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库.SSL协议库以及应用程序. 官网:http://www.openssl.org/OpenSSL for Windows:http:/ ...

  5. 单选按钮易忽略的Group属性

    Group就其意思就是一组的意思.就是说用于选择多个控件组合,选了TRUE后,你就可以为这组新建一个变量.把一组控件当一个控件来使用.例如多个单选按钮用group属性,这样你就可以用一个变量来管理这些 ...

  6. 慎得慌二u赫然共和任务i个屁

    http://www.huihui.cn/share/8424421 http://www.huihui.cn/share/8424375 http://www.huihui.cn/share/842 ...

  7. C++STL之set容器及stream类

    首先讲stream流类 头文件#include <sstream> 其功能是进行不同类型之间的转换,跟C语言 fscanf 和 fprintf 作用是同样的,可是比C语言的更简便更好用. ...

  8. struts2由&lt;s:tree&gt;要么dtree小工具 建立树

    一个 .<s:tree>方法: 1.引入新的标签: <%@ taglib prefix="sd" uri="/struts-dojo-tags" ...

  9. ios点击产生波纹效果

    ios点击产生波纹效果 by 伍雪颖 - (void)viewDidLoad { [super viewDidLoad]; RippleView = [[UIView alloc] initWithF ...

  10. 【UVA】12299-RMQ with Shifts(线段树)

    改动的时候因为数据非常小,所以能够直接暴力改动,查询的时候利用线段树即可了. 14337858 option=com_onlinejudge&Itemid=8&page=show_pr ...