We often talk about using memset correctly.
A problem was found in the previous project. The program always encountered an exception during the dynamic conversion of a dynamic_cast. After checking the problem for half a day, the problem was originally found in the use of memset. Although the problem itself is obvious, however, when there are hundreds of thousands of lines of code, it is not so easy to locate. This article summarizes several notes for using memset. Although the content is simple, I hope it will help you.
1. memset initializes memory blocks in bytes. When initializing an array of byte units, you can use memset to initialize each array unit to any value you want, for example,
char data[10];memset(data, 1, sizeof(data)); // rightmemset(data, 0, sizeof(data)); // right
Note the following when initializing other basic types,
int data[10];memset(data, 0, sizeof(data)); // rightmemset(data, -1, sizeof(data)); // rightmemset(data, 1, sizeof(data)); // wrong, data[x] would be 0x0101 instead of 1
2. When the struct type contains pointers, be careful when initializing with memset. For example, in the following code,
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 Unit pointed to by p_x is not initialized. Instead, the allocated p_x pointer is set to 0, causing memory leakage. Similarly, for std: vector and other data types, memset should obviously not be used for initialization.
3. When the struct or class itself or its base class has virtual functions, you need to use memset with caution. This problem is found in the initial project. In the following code,
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 when running the program to dynamic_cast. In fact, it is easy to find that our purpose is to initialize the data and buf in the data structure MyParameters. Normally, the memory space to be initialized is sizeof (int) * 3*2 = 24 bytes, but when memset is used to directly initialize the data structure of the MyParameters type, sizeof (my_pars) is 28 bytes, because in order to implement the polymorphism mechanism, C ++ will contain a pointer to the virtual function Table (V-Table) for objects with virtual functions. When memset is used, the pointer of the virtual function Table is also initialized to 0, while dynamic_cast also uses the RTTI technology, and V-Table will be used during runtime, at this time, the link with V-Table has been broken, causing an exception in the program.
How to Use memset to clear character arrays?
Both memsets are supported. Because 0 and '\ 0' are equivalent.
Note that a must be defined as char a [] = "xxxxxx", instead of char * a = "xxxxxx ".
Otherwise, the latter of sizeof (a) is a pointer of 4.
A [0] = '\ 0' can only write a 0 at the first character of a, that is, the string Terminator.
In fact, data is still available after a [1.
In a relative sense, if the control is correct, it cannot be cleared from the absolute "empty" perspective.
You must use the two memsets you have written.
Hope to be useful.
C ++ assigns values to the array and uses memset
Correct.
More accurate points should be:
Memset (& a [64], 0, sizeof (a)-64 * sizeof (char); // No difference since sizeof (char) = 1