首页 > 其他分享 >memset初始化类对象出错解析

memset初始化类对象出错解析

时间:2023-04-12 12:32:26浏览次数:29  
标签:初始化 obj int void memset 出错 指针


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 例程来初始化成员变量。

标签:初始化,obj,int,void,memset,出错,指针
From: https://blog.51cto.com/u_5746184/6185458

相关文章

  • 2023-04-11 使用react-draft-wysiwyg插件进行图片插入后编写文字时抛出错误:Unknown Dr
    前言:react+antd+react-draft-wysiwyg文本编辑业务场景,当我点击插入图片时,在该图片上一行或下一行进行文字输入会报如下错误:报错:UnknownDraftEntitykey:null.未知的DraftEntitykey:null。原因:当你插入图片时,新的图片img需要被包裹在一个块级元素内就不会报错(这看起来并不是原......
  • 二维数组的初始化
    ⑴分行进行初始化inta[2][3]={{1,2,3},{4,5,6}};在{}内部再用{}把各行分开,第一对{}中的初值1,2,3是0行的3个元素的初值。第二对{}中的初值4,5,6是1行的3个元素的初值。相当于执  行如下语句:inta[2][3];a[0][0]=1;a[0][1]=2;a[0][2]=3;a[1][0]=4;a[1][1]=5;a[1......
  • SAP销售订单开票报错科目确定期间出错的原因分析及解决方案 ​
    在SAP/ERP系统日常运维中,可能会遇到类似如下这样问题:在创建销售发票时候,系统报错提示如下,错误消息号:VF051。针对上图问题,要找到这问题的原因,首先需要了解下销售收入相关科目确定的配置逻辑销售收入相关科目确定的配置事务码:VKOASAP系统收入相关科目确定逻辑在一般情况下收入相关科......
  • spring——bean初始化过程解析
         ......
  • 源码共读 | tdesign-vue 初始化组件
    前言Tdesign-vue是一由腾讯开源的Vue.js组件库。我们知道,这些大型的组件库业务覆盖面很广,基本都包含了很多组件,很多组件包含了一些通用性代码,如果每开发一个组件,都去把这些通用性代码复制出来,无疑是非常繁琐的,那么作者在开发这些组件时是如何做的呢?学习目标:新增组件:npmrun......
  • Spring 源码解析 --Bean 的初始化流程
    --Spring原理架构图   --容器刷新  ---Bean初始化  --Bean生命周期流程 ......
  • Python小练习:权重初始化(Weight Initialization)
    Python小练习:权重初始化(WeightInitialization)作者:凯鲁嘎吉-博客园 http://www.cnblogs.com/kailugaji/调用Pytorch中的torch.nn.init.xxx实现对模型权重与偏置初始化。1.weight_init_test.py1#-*-coding:utf-8-*-2#Author:凯鲁嘎吉CoralGajic3#https://w......
  • C语言 静态变量的初始化
    一、C程序的内存分布C程序由下面5部分组成正文段(.text):通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常量,例如字符串常量等。初始化数据段(.data):通常是指用来存放程序中已初......
  • memset的用法详解
    memset的用法详解memset简介memset是一个初始化函数,作用是将某一块内存中的全部设置为指定的值。void*memset(void*s,intc,size_tn);s指向要填充的内存块。c是要被设置的值。n是要被设置该值的字符数。返回类型是一个指向存储区s的指针。需要说明的几个地方一、......
  • 【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】
    一、Aware接口&InitializingBean1、基础准备2、总结3、补充:EmbeddedValueResolverAware二、@Autowired和@PostConstruct注解失效1、基础准备2、失效情形3、失效原因4、使用Aware接口避免失效5、总结补充总结一、Aware接口&InitializingBean1、基础准备①编写MyBean实......