The previous project found a problem, the program is always in a dynamic_cast dynamic conversion out of the exception, looked for a long time only to find that the problem was in the use of memset, although the problem itself is obvious, but when in hundreds of thousands of lines of code in the magnitude, it becomes less easy to locate.
This article summarizes the use of memset a few needs to pay attention to the place, although the content is very simple, but also hope to be helpful to everyone.
1. Memset is the memory block initialized in bytes. When initializing an array of byte units, you can use Memset to initialize each array unit to whatever value you want, for example,
[CPP]View Plain copy
- Char data[10];
- memset (data, 1, sizeof (data)); // Right
- memset (data, 0, sizeof (data)); // Right
While initializing other base types, you need to be aware that, for example,
[CPP]View Plain copy
- 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. When a struct type contains pointers, care must be taken when using memset initialization. For example, in the following code,
[CPP]View Plain copy
- struct Parameters {
- int x;
- int* p_x;
- };
- Parameters par;
- par.p_x = new int[10];
- memset (&par, 0, sizeof (PAR));
When Memset is initialized, the value of the int array cell that the p_x points to is not initialized, but the p_x pointer that has already allocated memory is set to 0, causing a memory leak. Similarly, for data types such as std::vector, it is obvious that memset should not be used for initialization.
3. It is also prudent to use memset when there are virtual functions in the struct or class itself or in its base class. This is the problem that is found in the beginning of the project, in the following code,
[CPP]View Plain copy
- 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);
An exception occurred while the program was running to dynamic_cast. The reason is also very easy to find, our goal is to initialize the data structure myparameters data and buf, normally need to initialize the memory space is sizeof (int) * 3 * 2 = 24 bytes, However, when using memset to initialize the data structure of the myparameters type directly, sizeof (my_pars) is 28 bytes, because in order to implement the polymorphic mechanism, C + + has a pointer to the virtual function table (v-table) for the object with the virtual function. When using memset, the virtual function table pointer is also initialized to 0, and dynamic_cast also use Rtti technology, the runtime will use to v-table, at this time because the link with the v-table has been destroyed, resulting in an exception to the program.
Commonplace, correct use of memset