#include <iostream>

class Base1
{
private:
    char aChar;
    short aShort;
    int aInt;
    float aFloat;
};

class Derived1: public Base1
{
private:
    char charArray[3];
    short shortArray[3];
    int intArray[3];
    float floatArray[3];
    Base1 *ptrBase1;
};

class Base2
{
public:
    virtual ~Base2() {}
    virtual void virtualMethod() { std::cout << "virtualMethod" << std::endl; }
private:
    char aChar;
    short aShort;
    int aInt;
    float aFloat;
};

class Derived2 : public Base2
{
public:
    virtual ~Derived2() {}
private:
    char charArray[3];
    short shortArray[3];
    int intArray[3];
    float floatArray[3];
    Base2 *ptrBase2;
};

int main()
{
    Derived1 derived1;
    std::cout << sizeof(Derived1) << std::endl;
    std::cout << sizeof(Base1) << std::endl;
    memset(&derived1, 0, sizeof(Derived1));

    Derived2 derived2;
    std::cout << sizeof(Derived2) << std::endl;
    std::cout << sizeof(Base2) << std::endl;
    memset(&derived2, 0, sizeof(Derived2));
    derived2.virtualMethod();   // ok

    Base2 *ptrBase2 = new Derived2();
    memset(&ptrBase2, 0, sizeof(Derived2));
    ptrBase2->virtualMethod();  // crashes here

    delete ptrBase2;

    return 0;
}

/*
56
12
64
24
virtualMethod
段错误 (core dumped)
*/



结论:

1. 由 sizeof 的结果对比可知,成员方法是要占用对象的空间的。不过奇怪的是 Base1 到 Base2 增加了 12 字节,Derived1 到 Derived2 却只增加了 8 字节。

2. derived2.virtualMethod() 并没有 crash, 而 ptrBase2->virtualMethod() 却 crash 了,说明只有【动态绑定】时才会 crash, derived2.virtualMethod() 是编译阶段就确定了,memset 不影响。个人猜想是【动态绑定】时需要根据 vtable 在运行阶段确定函数地址,而 memset 却修改了这个地址,导致 crash。

(https://vctipsplusplus.wordpress.com/tag/memset-and-virtual-function/)


综上,当类中存在虚函数(包括类成员,典型的如类成员中含有 STL 中的 std::string 等)时,不要使用 memset, 排除这点还是可以使用 memset 的(目前还没有遇到其它情况不能用 memset 的)。