前项目发现一个问题,计划永远是一个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. 参考storm中的RotatingMap实现key超时处理

    storm0.8.1以后的RotatingMap完全可以独立于storm用来实现hashmap的key超时删除,并调用回调函数 RotatingMap.java: import java.util.H ...

  2. BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

    题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连 ...

  3. 算法-最长子序列和C/C++实现(三个复杂度)

    最长子序列和的问题非常easy: 就是一个数组,求出当中当中连续的某一段和,而这一段和是全部的连续段和的最大的值.求出这个值. 先说复杂度最高的:O(n3) 直接上代码,非常easy的: // // ...

  4. 更快地从IplImage转换成QImage

    转:http://blog.sina.com.cn/s/blog_5c70dfc80100qzif.html 在Qt平台上使用OpenCV肯定会遇到从IplImage到QImage的转换问题,找了很多 ...

  5. UVA11552------FEWEST FLOPS------区间型的DP

    题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. UVA - 12119 The Bells are Ringing (枚举)

    Perhaps you all have heard the mythical story about Tower of Hanoi (The details of this story is not ...

  7. uva 10129

    主要是求能否形成联通的欧拉回路 并查集+ 欧拉回路判断 一开始用dfs判断联通,死活A不出来,Wa了好多次………哭…… 并查集一次就AC了 感觉还是并查集代码好写一点, 因为dfs还要判断入口在哪里… ...

  8. uploadify,实际开发案例【选择完文件点击上传才上传】

    <script type="text/javascript"> )+Math.floor(Math.random()*)+']-'; //设置随机文件前缀. $k(fu ...

  9. 两道二分coming~

    第一道:poj 1905Expanding Rods 题意:两道墙(距离L)之间架一根棒子,棒子受热会变长,弯曲,长度变化满足公式( s=(1+n*C)*L),求的是弯曲的高度h. 首先来看这个图: ...

  10. perl的一些基本用法

    ReadLine support available (try 'install Bundle::CPAN')cpan>进入cpan的shell,好了,我为了安装spamassassin,需要安 ...