Understand pointer and memory leakage in C and how to avoid it

Source: Internet
Author: User

If you are tired of debugging pointers and memory leaks when using C language, this article will show you the pointer operation types that may cause memory corruption, you will also study some scenarios to find out what issues to consider when using dynamic memory allocation.

Introduction

For anyone who uses the C language, if they ask what is the biggest headache of the C language, many may say pointer and memory leaks. This does consume most debugging time for developers. Pointer and memory leaks seem daunting for some developers, but once you understand the basics of pointers and their associated memory operations, they are the most powerful tool in the C language.

This article will share with you the secrets developers should know before using pointers for programming. This article includes:

Pointer operation type that causes memory corruption
Checkpoints that must be considered when dynamic memory allocation is used
Scenarios that cause memory leakage

If you know in advance where an error may occur, you can avoid traps and eliminate most of the issues related to pointers and memory.


Where can an error be reported?

Several problems may occur, which may cause problems after generation. When processing pointers, you can use the information in this article to avoid many problems.

Uninitialized memory

In this example, p is allocated with 10 bytes. These 10 bytes may contain junk data, as shown in Figure 1.

Char * p = malloc (10 );

Figure 1. Junk data


If you try to access a code segment before assigning a value to this p, you may get the garbage value, and your program may have unpredictable behavior. P may have a value that your program never expected.

A good practice is to always use memset and malloc together, or use calloc.

Char * p = malloc (10 );
Memset (p, '\ 0', 10 );

Now, even if the same code segment tries to access it before assigning a value to p, the code segment can correctly handle Null values (values that should be appropriate in an ideal situation) and then have the correct behavior.

Memory Coverage

Since p has been allocated with 10 bytes, if a code snippet attempts to write an 11-byte value to p, this operation will automatically "eat" one byte from another location without telling you. Let's assume that the pointer q represents the memory.

Figure 2. Original q content


Figure 3. Overwrite q content


As a result, the pointer q will have unexpected content. Even if your module is properly encoded, it may be incorrect because a co-located module performs some memory operations. The following sample code snippet also describes this scenario.

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

In this example, the memcpy operation attempts to write 11 bytes to p, while the latter is only allocated 10 bytes.

As a good practice, every time you write a value to a pointer, make sure that the number of available bytes and the number of written bytes are checked. In general, the memcpy function will be a checkpoint for this purpose.

Memory read out of bounds

Overread refers to the number of bytes read more than the expected bytes. This issue is not very serious and will not be detailed here. The following code provides an example.

Char * ptr = (char *) malloc (10 );
Char name [20];
Memcpy (name, ptr, 20); // Problem begins here

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

Memory leakage

Memory leakage may be annoying. The following list describes some scenarios that cause memory leakage.

Assign a value again

I will use an example to illustrate the problem of re-assignment.

Char * memoryArea = malloc (10 );
Char * newArea = malloc (10 );

This value is assigned to the memory position shown in Figure 4 below.

Figure 4. Memory location

   

MemoryArea and newArea are allocated 10 bytes respectively. Their respective contents are shown in figure 4. If someone executes the following statement (the pointer is assigned a value again )......

MemoryArea = newArea;

It will certainly cause you trouble in the subsequent stages of the module development.

In the preceding code statement, the developer assigns the memoryArea pointer to the newArea pointer. As a result, the memory location previously pointed to by memoryArea becomes isolated, as shown in figure 5 below. It cannot be released because there is no reference pointing to this location. This results in 10 bytes of memory leakage.

Figure 5. Memory leakage

   

Before assigning values to pointers, make sure that the memory location is not isolated.

First release the parent block

Suppose there is a pointer memoryArea, which 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 figure 6.

Figure 6. Dynamically allocated memory

Free (memoryArea)

If memoryArea is released by calling free, the newArea pointer becomes invalid. The memory location previously pointed to by newArea cannot be released because there is no pointer to this location. In other words, the memory location pointed by newArea becomes isolated, resulting in memory leakage.

Whenever a structured element is released and the element contains a pointer to the dynamically allocated memory location, you should first traverse the sub-memory location (newArea in this example) and release it from there, and then traverse back to the parent node.

The correct implementation here should be:

Free (memoryArea-> newArea );
Free (memoryArea );

Incorrect processing of returned values

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

Char * func ()
    {
Return malloc (20); // make sure to memset this location to '\ 0 '...
    }

Void callingFunc ()
    {
Func (); // Problem lies here
    }

In the preceding example, the return address of the memory location is not processed when calling the func () function in the callingFunc () function. As a result, the 20-byte block allocated by the func () function is lost, resulting in memory leakage.

Return

A large amount of dynamic memory allocation may exist during component development. You may forget to keep track of all pointers (pointing to these memory locations), and some memory segments are not released and are still allocated to the program.

Always track all memory allocations and release them whenever appropriate. In fact, you can develop a mechanism to track these distributions, such as retaining a counter in the linked list node itself (but you must also consider the additional overhead of this mechanism ).


Access a null pointer

It is very dangerous to access a null pointer because it may cause your program to crash. Always make sure that you are not accessing the null pointer.

Summary

This article discusses several traps that can be avoided when dynamic memory allocation is used. To avoid memory problems, good practices are as follows:

Always use memset and malloc together, or always use calloc.
When writing a value to the pointer, make sure that the number of available bytes and the number of written bytes are checked.
Before assigning values to pointers, make sure that no memory location is isolated.
Whenever a structured element is released (and the element contains a pointer to the dynamically allocated memory location), the sub-memory location should be traversed and released from there, and then traverse back to the parent node.
Always correctly handle the return value of the function referenced by the dynamically allocated memory.
Each malloc must have a corresponding free.
Make sure that you are not accessing the null pointer.

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.