Today I meet a memory leaks error in my program and I always cannot find the place where memory leaks happen. Though I use MS Memory Leaks Detect Tricks, it doesn't help. This is because STL memory leaks cann't be found by this trick, I think. I almost spent half day to find the solution, so I'll write down this problem and the solution for you and me.
About two months ago, I wrote a Material Class for Obj format model:
class Material { public: Material(){ setDefaults();} void setDefaults(){ memset(this,0,sizeof(*this));} int mark; char materialName[256]; // material name Vector3 ambient; // ambient Vector3 diffuse; // diffuse Vector3 specular; // specular int shininess; // float alpha; // bool isSpecular;As we all know, the above codes runs good. It uses C-style initialize method "memset" to set class attributes to be zero. But today, I want to reuse these codes with C++ style, so I rewrite the codes:char textureName[256]; // texture name char textureTransName[256]; // transparent texture name
};
class Material { public: Material(){ setDefaults();} void setDefaults(){ memset(this,0,sizeof(*this));} int mark; std::string materialName; // material name Vector3 ambient; // ambient Vector3 diffuse; // diffuse Vector3 specular; // specular int shininess; // float alpha; // bool isSpecular;Do you think these codes are ok for my progam? NO!, if you use this class in your project, you will have Memory Leaks! and you will never know the problem is caused by this class. You will get errors as follows:std::string textureName; // texture name std::string textureTransName; // transparent texture name
};
3{235250} normal block at 0x01774A60, 16 bytes long. 4 Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 5{235237} normal block at 0x01774CB0, 16 bytes long. 6 Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 7{235234} normal block at 0x01774A10, 16 bytes long. 8 Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
The reason why this problem occurs is that you use C-style initialize method "memset" for C++ object "std::string". Please never use memset in your new C++ program which struct/class has C++ objects ( such as vector, string objects ).
So, the solution is that you should initialize the variable manually with C++ style.
class Material { public: Material(){ setDefaults();} void setDefaults() { this->ambient = Vector3( 0.2f, 0.2f, 0.2f ); this->diffuse = Vector3( 0.8f, 0.8f, 0.8f ); this->specular = Vector3( 1.0f, 1.0f, 1.0f ); this->shininess = 0; this->alpha = 1.0f; this->isSpecular = false; this->textureName = ""; this->textureTransName = ""; this->mark = 0; } int mark; std::string materialName; // material name Vector3 ambient; // ambient Vector3 diffuse; // diffuse Vector3 specular; // specular int shininess; // float alpha; // bool isSpecular;Good Luck for you!std::string textureName; // texture name std::string textureTransName; // transparent texture name
};