Pointers and memory leaks in C language in several cases

Source: Internet
Author: User

Introduction

Original address: http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html, reprint Please indicate the source address.

For anyone using C language, if asked what the biggest annoyance of C language is, many of them might answer pointers and memory leaks. These are really things that consume most of the developer's debugging time. Pointers and memory leaks may seem daunting to some developers, but once you understand the basics of pointers and their associated memory operations, they are the most powerful tools you have in C.

This article will share with you the secrets that developers should know before starting to use pointers for programming. The contents of this article include:

    • Type of pointer action that causes memory corruption
    • Checkpoints that must be considered when using dynamic memory allocation
    • Scenarios that cause memory leaks

If you know in advance what can go wrong, you can be careful to avoid traps and eliminate most of the pointers and memory related issues.

Where could something go wrong?

Several problem scenarios may occur, which can cause problems after the build is complete. As you work with pointers, you can use the information in this article to avoid many problems.

Common memory errors and their countermeasures are as follows:

1, the memory allocation is not successful, but used it

Novice programmers often make this mistake because they are unaware that the memory allocation will not succeed. A common workaround is to check if the pointer is NULL before using memory . If the pointer p is a function parameter, then the function

The entrance is checked with an assert (P!=null). If you are using malloc or new to request memory, you should 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: one is the idea of no initialization, and the other is to mistakenly assume that the default initial value of the memory is all zero, resulting in a reference to the initial error (for example, an array).

There is no uniform standard for what the default initial value of memory is, although sometimes it is a zero value and we would rather believe it to be credible. So no matter how you create an array, don't forget to assign the initial value, even if it's 0.

The value can not be omitted, do not be too troublesome.

3. The memory allocation succeeds and has been initialized, but the operation crosses the memory boundary

For example, the use of arrays often occurs when the subscript "more 1" or "less 1" operation. Especially in a For loop statement, the number of loops can be easily mistaken, resulting in array operations being out of bounds.

4, forget to release memory, causing memory leaks

The function that contains this error loses one piece of memory each time it is called. At first, the system has plenty of memory and you can't see the error. One time the program suddenly died, the system appears prompt: memory exhaustion.

Uninitialized memory

In this example, p 10 bytes have been allocated. These 10 bytes may contain garbage data, as shown in 1.

Char *p = malloc (10);

Figure 1. Junk data

If p a snippet tries to access it before it is assigned to it, it may get garbage values, and your program may have unpredictable behavior. pmay have a value that your program has never expected.

Good practice is always used in combination memset with malloc , or used calloc .

Char *p = malloc (P, ' memset ', 10);

Now, even if the same piece of code tries to p access it before it is assigned, the snippet also handles the Null value correctly (ideally, the value it should have) and then has the correct behavior.

Memory overwrite

Since p 10 bytes have been allocated, if a code fragment tries to p write a 11-byte value, the action will automatically "eat" a byte from a different location without telling you. Let's assume q that the pointer represents that memory.

Figure 2. Original Q content

Figure 3. Post-Coverage Q content

As a result, the pointer q will have something that was never expected. Even if your module is well-coded, it may behave incorrectly due to certain memory operations performed by a co-existing module. The following sample code snippet can also illustrate this scenario.

Char *name = (char *) malloc (11); Assign some value to namememcpy (p,name,11); Problem begins here

In this case, the memcpy operation attempted to write 11 bytes p , and the latter was only assigned 10 bytes.

As a good practice, whenever you write a value to a pointer, make sure that you cross-check the number of bytes available and the number of bytes written. In general, the memcpy function will be the checkpoint for this purpose.

Memory read out of bounds

Memory read out-of-bounds (overread) refers to the number of bytes read more than the number of bytes they should have. The problem is not too serious and is not detailed here. The following code provides an example.

Char *ptr = (char *) malloc (n); char name[20]; memcpy (name,ptr,20); Problem begins here

In this example, the memcpy operation attempts to ptr read from 20 bytes, but the latter is only assigned 10 bytes. This can also lead to unwanted output.

Memory leaks

Memory leaks can be really annoying. The following list describes some scenarios that cause a memory leak.

    • Re-assign Value

      I'll use an example to illustrate the question of re-assignment.

Char *memoryarea = malloc (n), char *newarea = malloc (10);

This assigns a value to the memory location shown in Figure 4 below.

Figure 4. Memory location

memoryAreaand newArea respectively are assigned 10 bytes, which are shown in their respective content 4. If someone executes a statement such as the following (pointer re-assigned value) ...

Memoryarea = Newarea;

It will certainly bring you trouble in the next stages of the module development.

In the preceding code statement, the developer assigns the memoryArea pointer to the pointer newArea . As a result, the memoryArea previously pointed memory location becomes orphaned, as shown in Figure 5 below. It cannot be freed because there is no reference to that location. This results in a 10-byte memory leak.

Figure 5. Memory leaks

Make sure that the memory location does not become orphaned before you assign a value to the pointer.

    • First release the parent block

      Suppose you have a pointer memoryArea that points to a 10-byte memory location. The third byte of the memory location points to a dynamically allocated 10-byte memory location, as shown in 6.

If you release by calling Free memoryArea , the newArea pointer becomes invalid as a result. newAreathe memory location pointed to previously cannot be freed because there are no pointers to that location. In other words, the newArea location of the pointing memory becomes orphaned, resulting in a memory leak.

Whenever a structured element is released, and the element contains a pointer to a dynamically allocated memory location, the child memory location (in this case) should be traversed first, newArea and then freed from there and then traversed back to the parent node.

The correct implementation here should be:

Free (Memoryarea->newarea), free (Memoryarea);
    • Incorrect handling of return values

      Sometimes, some functions return a reference to dynamically allocated memory. Tracking the memory location and handling it correctly becomes the calling function's responsibility.

      Char *func () {    return malloc (+);//Make sure to memset the "to" ...} void Callingfunc () {    func ();//Problem lies here}

      In the previous example, the callingFunc() call to the function in the function func() did not process the return address of the memory location. As a result, the func() 20-byte block allocated by the function is lost and causes a memory leak.

Return what you have obtained.

There may be a lot of dynamic memory allocations when developing components. You may forget to track all pointers (pointing to these memory locations), and some memory segments are not released and remain assigned to the program.

Always keep track of all memory allocations and release them at any appropriate time. In fact, you can develop a mechanism to track these allocations, such as keeping a counter in the list node itself (but you must also consider the additional overhead of the mechanism).

Accessing a null pointer

Accessing a null pointer is dangerous because it can cause your program to crash. Always make sure that you are not accessing a null pointer.

Summarize

This article discusses several pitfalls that you can avoid when using dynamic memory allocation. To avoid memory-related problems, good practice is:

    • Always use together memset and malloc, or always use calloc .
    • Whenever you write a value to a pointer, be sure to cross-check the number of bytes available and the number of bytes written.
    • Make sure that no memory location becomes orphaned before you assign a value to the pointer.
    • Whenever you release a structured element that contains a pointer to a dynamically allocated memory location, you should first traverse the child memory location and start releasing it from there, and then traverse back to the parent node.
    • function return values that return dynamically allocated memory references are always handled correctly.
    • Each malloc must have a corresponding free.
    • Make sure that you are not accessing a null pointer.

Pointers and memory leaks in C language in several cases

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.