Knowledge of memory management in C + +

Source: Internet
Author: User
Tags strcmp

Memory allocation method

There are three ways to allocate memory:
(1) Allocation from a static storage area. Memory is allocated at the time of program compilation, and the entire running period of the program is present in this block. For example, global variables, static variables.
(2) Create on the stack. When executing a function, the storage units of local variables within the function can be created on the stack, which are automatically freed when the function is executed at the end. The stack memory allocation operation is built into the processor's instruction set and is highly efficient, but allocates limited memory capacity.
(3) Allocation from the heap, also known as dynamic memory allocation. When the program is running, it uses malloc or new to request any amount of memory, and the programmer is responsible for freeing the memory with free or delete. The lifetime of dynamic memory is determined by us and is very flexible to use, but the problem is the most.

Common memory errors and their countermeasures

Common memory errors and their countermeasures:

(1) The memory is not allocated successfully, but it is used.

Checks if the pointer is NULL before using memory, if the pointer p is the function's argument, check with assert (P! = null) at the entrance of the function, if you are using malloc or new to request memory, use if (p = = null) or if (p!=null) For error-proof handling.

(2) The memory allocation succeeds, but it is not initialized to reference it

There are two main causes of this error:
1. There is no concept of initialization.
2. Mistakenly assume that the default initial value of memory is 0, resulting in a reference error.

(3) The memory allocation succeeds and has been initialized, but the manipulation crosses the bounds of the memory (4) Forgetting to free memory, causing memory leaks

A function with this error is missing a piece of memory once it is called.
Dynamic memory application and release must be paired, the program malloc and free use must be the same number, otherwise there must be errors (new/delete).

(5) Release and continue to use it

There are three possible scenarios:
1. The object electrophoresis relationship in the program is too complex, it is difficult to know whether an object has freed the memory, at this time should redesign the data structure, fundamentally solve the chaos of object management.
2. The return statement of the function is incorrectly written, note that you do not return a pointer or reference to "stack memory" because the memory is automatically destroyed at the end of the function body.
3. After releasing memory with free or delete, the pointer is not set to null. Causes the "wild pointer" to be produced.
Considerations for using Memory allocations:
1. After requesting memory with malloc or new, you should immediately check that the pointer value is NULL. Prevents the use of memory with a pointer value of NULL.
2. Do not forget to assign an initial value to both arrays and dynamic memory. Prevents memory that is not initialized from being used as the right value.
3. Avoid array or pointer subscript out of bounds, especially beware of "more than 1" or "less 1" operation.
4. The application and release of dynamic memory must be paired to prevent memory leaks.
5. After releasing memory with free or delete, set the pointer to NULL immediately, preventing the "wild pointer" from being produced.

Comparison of pointers to arrays

Arrays are either created in a static store (such as a global array) or created on a stack. The array name corresponds to (instead of pointing to) a piece of memory whose address and capacity remain constant over the lifetime, and only the contents of the array can be changed.
Pointers can point to any type of block of memory at any time, and his characteristics are "mutable", so we use pointers to manipulate dynamic memory. Pointers are far more flexible than arrays, but they are also more dangerous.

1. Modify the Content

In example 7-3-1, the capacity of the character array A is 6 characters and its contents are hello\0. The contents of a can be changed, such as a[0]= ' X '. The pointer p points to the constant string "world" (in the static store, the content is world\0), and the contents of the constant string cannot be modified. Syntactically, the compiler does not feel anything wrong with the statement p[0]= ' X ', but the statement attempts to modify the contents of the constant string to cause a run error.

char a[] = “hello”;a[0] = ‘X’;cout << a << endl;char// 注意 p 指向常量字符串p[0// 编译器不能发现该错误cout << p << endl;
2. Content replication and comparison

The statement p = A does not copy the contents of a pointer p, but assigns the address of A to P. To copy the contents of a, you can use the library function malloc for p to request a piece of memory with a capacity of strlen (a) + 1 characters, and then use strcpy for string copying. Similarly, the statement if (p==a) comparison is not the content but the address, should be compared with the library function strcmp.

//Array AssignmentCharA[] ="Hello";Charb[Ten];strcpy(b, a);//cannot be used with B = A;if(strcmp(b, a) = =0)//cannot be used if (b = = a)//Pointer assignmentintLen =strlen(a);Char*p = (Char*)malloc(sizeof(Char) * (len+1));strcpy(P,a);//Do not use P = A;if(strcmp(p, a) = =0)//Do not use if (p = = a)
3. Calculate Memory capacity

Use the operator sizeof to calculate the capacity (in bytes) of the array. The value of sizeof (a) is 12 (be careful not to forget ' s '). Pointer p points to a, but sizeof (p) has a value of 4. This is because sizeof (p) Gets the number of bytes of a pointer variable, which is equivalent to sizeof (char*), not the memory capacity referred to by P.

char"hello world";char *p = a;coutsizeof// 12 字节coutsizeof// 4 字节

Note that when an array is passed as an argument to a function, the array is automatically degraded to a pointer of the same type.

void Func(char a[100]){    coutsizeof// 4 字节而不是 100 字节}
How is the pointer parameter passing memory?

If the parameter of the function is a pointer, do not expect to use the pointer to apply dynamic memory.

void  getmemory (char  *p, int  num) {p = (char
      *) malloc (sizeof (char ) * num);} void  Test (void ) {char  *    str  = NULL; GetMemory (str , 100 ); //str is still NULL  strcpy (str , " "Hello" ); //Run error }  

The

Test function's statement getmemory (STR,200) does not have the desired memory for STR, and STR is still null. The
compiler makes a temporary copy of each function of the function, and the copy of the pointer parameter P is _p, and the compiler causes _p = p. If the program inside the function modifies the contents of the _p, it causes the contents of the parameter p to be modified accordingly. In this case, _p applied for new memory, but changed the memory address referred to by _p, but P did not change. So getmemory can't output anything.
If you want to use pointer parameters to request memory, you should instead use a pointer to pointer

void GetMemory2(charint num){    *p = (char *)malloc(sizeof(char) * num);}void Test2(void){    char *str = NULL;    GetMemory2(&str100// 注意参数是 &str,而不是 str    strcpy(str"hello");    str << endl;    free(str);}

Since the concept of pointers to pointers is not easy to understand, we can use function return values to pass dynamic memory.

char *GetMemory3(int num){    char *p = (char *)malloc(sizeof(char) * num);    return p;}void Test3(void){    char *str = NULL;    str = GetMemory3(100);     strcpy(str"hello");    str << endl;    free(str);}

Do not return a pointer to "stack memory" with a return statement because the memory automatically dies at the end of the function.

char *GetString(void){    char"hello world";    return// 编译器将提出警告}void Test4(void){    char *str = NULL;    str// str 的内容是垃圾    str << endl;}

Stepping through the debugger to trace Test4, it is found that although STR is no longer a NULL pointer after executing the STR = GetString statement, STR's content is not "Hello World" but rather garbage memory. Continue to modify the program.

char *GetString2(void){char"hello world";return p;}void Test5(void){char *str = NULL;strstr << endl;}

The function Test5 runs without errors, but the design concept of the function GetString2 is wrong. Because the "Hello World" in GetString2 is a constant string, it is located in a static store, which is constant throughout the lifetime of the program. Whenever GetString2 is called, it always returns the same "read-only" block of memory.

What happened to free and delete pointers?

Free and delete simply release the memory that the pointer refers to, but do not kill the pointer itself.
P is free after its address remains unchanged (non-null), except that the address of the memory is garbage, p becomes a "wild pointer", if you do not set p to null, it will make people mistakenly think that P is a legitimate pointer.

Will dynamic memory be released automatically?

(1) The pointer dies, and does not mean that the memory it refers to is automatically released.
(2) The memory is freed and does not indicate that the pointer is extinct or is a null pointer.

Eliminate "wild hands"

The "Wild pointer" is not a null pointer, it is a pointer to "junk" memory.
There are two main causes of the "wild pointer":

(1) The pointer variable is not initialized. Any pointer variable that has just been created does not automatically become a null pointer, and its default value is random, and it can be arbitrary. So the pointer variable should be initialized at the same time it was created, either by setting the pointer to null or by pointing it to legitimate memory.

For example:

char *p = NULL;char *str = (char *)malloc(100);
(2) The pointer p is not set to null after the free or delete, which makes the person mistakenly think P is a valid pointer. (3) The pointer operation goes beyond the scope of the variable.
class A{     public:     void Func(voidofclass A” << endl; }};void Test(void){     A *p;     {          A a;          // 注意 a 的生命期     }     // p 是“野指针”}

When the function Test executes the statement p->func (), object A has disappeared, and P is pointing to a, so p becomes the "wild pointer". But the strange thing is that I ran this program without error, which may be related to the compiler.

Why do you want to new/delete with Malloc/free?

malloc and free are the c++/c functions of the language, and New/delete is the operator of C + +.
For objects of non-intrinsic data types, light Malloc/free cannot meet the requirements of dynamic objects. Objects are automatically executed when they are created, and the object executes the destructor automatically before it dies. Because Malloc/free is a library function and not an operator, the task of executing constructors and destructors cannot be imposed on Malloc/free without the compiler controlling permissions.
So the C + + language requires an operator new that can perform dynamic memory allocation and initialization, and an operator delete that cleans and frees memory, noting that New/delete is not a library function.

What if I run out of memory?

There are typically three ways to handle memory exhaustion issues. (There is almost no memory exhaustion in the currently used Windows operating system)
(1) Determine if the pointer is NULL, and if so, terminate the function with the return statement immediately. For example:

void Func(void){     A *aA;     if(a == NULL)     {          return;     }     …}

(2) Determine if the pointer is NULL, and if so, use Exit (1) to terminate the entire program operation immediately. For example:

void Func(void){     new A;     if(a == NULL)     {          cout << “Memory Exhausted” << endl;          exit(1);     }     …}

(3) Set exception handling functions for new and malloc. For example, Visual C + + can use the _set_new_hander function to set a user-defined processing function for new, or to allow malloc to enjoy the same exception handler as new.

Key points of use of Malloc/free

The prototype of the function malloc is as follows:
void *malloc (size_t size);
Use malloc to apply for a piece of the length of the shape type of the content,
int p = (int ) malloc (sizeof (int) * length);
We should focus on two elements: "Type conversion" and "sizeof".
The malloc return value is void , so type conversions are explicitly made when malloc is called, and void is converted to the desired pointer type.
The malloc function itself does not recognize what type of memory to request, it only cares about the total number of bytes in memory.
Prototype of function free
void free (void * memblock)
Why is the free function not as complex as the malloc function? This is because the type of the pointer p and the amount of memory it refers to is known beforehand, and the statement free (p) frees the memory correctly. If P is a NULL pointer, then free has no problem with P no matter how many times it is manipulated. If P is not a NULL pointer, then the free p
Running the operation two times will cause the program to run incorrectly.

Key points of use of New/delete

int p1 = (int ) malloc (sizeof (int) * length);
int *p2 = new Int[length];
The new built-in sizeof, type conversion, and type safety check functionality. For objects of non-intrinsic types, new initializes the initialization work while creating the dynamic object.

class Obj{public :     Obj(void// 无参数的构造函数     // 带一个参数的构造函数     …}void Test(void){     new Obj;     new Obj(1// 初值为 1     …     delete a;     delete b;}

If you create an array of objects with new, you can only use the parameterless constructor of the object.
For example

new Obj[100// 创建 100 个动态对象

Cannot be written

Obj *objects = new Obj\[100](1);// 创建 100 个动态对象的同时赋初值 1

When releasing an array of objects with delete, be careful not to lose the symbol ' [] '. For example

delete// 正确的用法delete// 错误的用法

The latter is equivalent to delete objects[0], missing another 99 objects.

Refer to Dr. Lin Yue's "high quality C + + Programming Guide"

Knowledge of memory management in C + +

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.