memset函数:不当使用memset函数带来的麻烦问题



通常在C编程中我们经常使用mem块连续内存区域清零或设置为其它指定最近在移植段java代码到C时候不当使用mem花费了我几个小时调试时间对于虚底层机制很多资料都有较详细阐述但对我个人而言这次调试让我感触颇深

先来看段代码在继承类Advance的中有很多属性字段我希望将其清成0或NULL于是在构造中我通过mem将当前类所有属性置0

Base{

public:

virtual void kickoff = 0;

};



Advance:public Base{

public:

Advance{

mem(this, 0, (Advance));

}

void kickoff{

count;

//... do something ;

}

private:

attr1, attr2;

char* label;

count;

//... other attributes, they should be initiated to 0 or NULL at beginning.

};







_t( argc, _TCHAR* argv)

{



Base* ptr = Advance;

ptr->kickoff;



0;

}

这样看似能正常运行但运行你会发现类似于下面:

TestVirtual.exe 中 0x00415390 处未处理异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突

同时断点停留在ptr->kickoff提示我们可以得知无法kickoff思路方法这个思路方法指针没有被正确但为什么呢?

指出问题的前先看看这段文献上有关虚机制介绍说明:

赖以生存底层机制:vptr + vtable运行时实现采用了VPTR/VTBL形式这项技术基础:
①编译器在后台为每个包含虚类产生个静态指针(虚表)在这个类或者它基类中定义个虚都有个相应指针
②每个包含虚个例子包含个不可见数据成员vptr(虚指针)这个指针被构造自动指向类vtbl(虚表)
③当客户时候编译器产生代码反指向到vptr索引到vtbl中然后在指定位置上找到指针并发出

这里问题就出在

mem(this, 0, (Advance));

上面指针应该在进入构造赋值体的前自动而mem却又将已经化好指针清0了这就是为什么会产生上面访问零址将上面mem语句去除就可以正常运行了

所以从上面问题中我们可以看出在构造体内mem将整个对象清0是很有风险当没有虚时候上面可以正常运行(可以试着将Base类纯虚声明改成非虚再运行)化类属性对象时比较稳妥办法还是手动逐个进行初使化

Tags:  memset怎么用 memset头文件 memset memset函数

延伸阅读

最新评论

发表评论