C language - Memory Management

In computer systems, particularly embedded systems, memory resources are very limited. Especially for mobile end developers, limited by the hardware resources makes it a problem in programming the primary consideration is how to effectively manage memory resources. This paper is made in the process of learning C language memory management in a summary, if wrong place, hope readers hesitate to correct me.

First, a few basic concepts

  In the C language, knowledge about memory management more, such as functions, variables, scope, pointers, while exploring the C language memory management mechanism, under which briefly review a few basic concepts:

1. Variable: do not explain. But need to figure out which of several types of variables:

  • Global variables (external variables): variable appears outside the block {} it is a global variable.
  • Local variables (automatic variables): In general, {} block internal variable is defined automatic variables can also be used auto display definition.
  • Static variables: the variable refers to the memory location during program execution has not changed, modified with the keyword static. Static variable inside the code block can only be accessed by the internal code block, the code block external static variables can only be defined variable access this file.

Note: extern variable modified, depending on the circumstances, can be seen as both definitions can also be seen as a statement; but when modified extern function can only be defined, there is no ambiguity.

2. Scope: generally refers to the scope of the variable, broadly speaking, there are function scope and the file scope and so on. I understand the scope refers to the area or scope of a thing can exist, such as a drop of water can exist only between 0-100 degrees Celsius, beyond that, broadly speaking "water" does not exist, it becomes into the ice or gas.

3. Functions: do not explain.

Note: C language functions are global by default, you can use the static keyword to declare a function static function (defined functions can only be accessed by a file of this function).

Second, the four areas of memory

  Computer memory is partitioned to manage the memory between programs and procedures are independent, can not visit each other, such as memory areas and QQ browser share, respectively, are not interchangeable visit. The memory is partitioned management of each program, an application can share the memory is divided into many areas, we need to understand there are four main areas, usually called the four areas of memory, as shown below:

 

                                           

1. Area Code

  The operating system program is loaded into memory when all of the executable code (program code instructions, a constant string, etc.) are loaded into the code area, this memory during running is constant. Parallel code area, which is filled with a bunch of instructions, during the program run can not be changed. Function is also part of the code, so that functions are placed in the code region, comprising a main function.

  Note: "int a = 0;" statement can be split into "int a;" and "a = 0", the definition of variable a "int a;" statement is not a code, which is executed when the program is compiled, and not put code area, only the code area into "a = 0" phrase.

2. Static area

  Static program storage area in all global and static variables.

3. Stack area

  Stack (stack) is out after an advanced memory architecture, all automatic variables, function parameter are stored on the stack, this action is completed automatically by the compiler, we need to consider when writing programs. Stack area during program execution can be modified at any time. When an automatic variable exceeds its scope, automatically ejected from the stack.

  • Each thread has its own stack;
  • The maximum size of the stack is fixed, beyond the stack overflow is caused;
  • Memory on the stack will be automatically released after the variable goes out of scope.

  Talk is cheap, show you the code:

Copy the code

// Experiment 1: memory address code area observed, static area, stack area

#include "the stdafx.h"
int n-= 0;
void Test (int a, int b)
{
the printf ( "in the form of a parameter address is:% d \ n form parameter b is the address:% d \ n", & a , & B);
}
int the _tmain (int argc, _TCHAR * the argv [])
{
static int m = 0;
int a = 0;
int B = 0;
the printf ( "auto-variable a address:% d \ n automatic variable b's address is:% d \ n ", & a, & b);
the printf (" global variable n address:% d \ n static variable m address:% d \ n ", & n, & m);
Test ( a, B);
the printf ( "_ address tmain function is: D%", the _tmain &);
getchar ();
}

Copy the code

  Results are as follows:

                                                                         

  Result Analysis: automatic variables a and b are defined and assigned in turn, are stored in the stack area, the memory address only a difference of 12, should be noted that the address of a larger than b, because the stack is advanced out of the latter data storage structure, the first storage, a, after storage, b, as shown above represents visualization (note address number order). Once out of scope, the variable b will precede a variable is destroyed. This is much like the clothes put into the box, the last to be the first to put out the last of the first to be put out.

Copy the code
// Experiment two: stack variables and scope 
#include "stdafx.h"
return value is a pointer // function, although this can run the program, but this is not legitimate, because
// need to do this in a non x variable by static keyword before modification, i.e. A = 0 int static;
int * getX () { int x = 10; return &x; } int _tmain(int argc, _TCHAR* argv[]) { int *p = getx(); *p = 20; printf("%d", *p); getchar(); }
Copy the code

  This code has no syntax errors, but also to get the desired results: 20. But writing is so problematic: because () variable int * p = getx x scope for the internal () function body getx, here to get the address of a temporary stack variable x, getx () after the end of the address of the function call invalid, but the back * p = 20 still be accessed and modified, the results may also be wrong for the actual work should avoid this practice, or do not know how to die. You can not address a stack variable return by the return value of the function, remember!

  In addition, the stack will not be great, usually in K. If a large stack variables directly stored in an array of functions in the program, the memory is likely to overflow, causing the program to crash (as third experiment), strictly speaking, should be called stack overflow (when the stack space is full, but also variable pressure to the stack memory, this is called a stack overflow).

Copy the code
// third experiment: to see what is stack overflow 
int _tmain (int argc, _TCHAR * argv []) { char array_char[1024*1024*1024] = {0}; array_char[0] = 'a'; printf("%s", array_char); getchar(); }
Copy the code

How to do? This time in relation to pile into play.

4. heap area

  Heap (heap) and stack, as is also a program is running in memory regions can be modified at any time, but not as advanced post-stack order out. More importantly, the heap is a large container, its capacity is much larger than the stack, it can be difficult to solve the three memory overflow caused by the experiment above. Generally more complex data types are on the heap. However, in C language, the application and release heap memory space need to manually done by the code. For a 32-bit operating system, the maximum Management 4G memory, which is the operating system 1G own use, and the rest are 3G to the user program, a user program can theoretically use 3G memory space. Heap memory must be manually released (C / C ++), unless the language execution environment GC (such as C # running on .NET have garbage collection). How pile of memory usage?

  Next, look to allocate and free heap memory:

malloc and free

  malloc function to allocated in the heap memory specified size, in bytes (Byte), void * function returns a pointer; Free responsible for the release of the heap memory allocated by malloc. malloc and free must be used in pairs . See the examples below:

Copy the code
// Experiment 4: problem solving stack overflow 
#include "stdafx.h" #include "stdlib.h" #include "string.h" void print_array(char *p, char n) { int i = 0; for (i = 0; i < n; i++) { printf("p[%d] = %d\n", i, p[i]); } } int _tmain(int argc, _TCHAR* argv[]) { char * p = (char *) malloc (1024 * 1024 * 1024); // in the application heap memory memset (p, 'a', sizeof (int) * 10); // initialize the memory int i = 0; for (i = 0; i < 10; i++) { p[i] = i + 65; } print_array(p, 10); free (p); // release the application heap memory getchar(); }
Copy the code

Operating results as follows:

   Program can run normally, this would resolve the experiment just three stack overflow problem. How large the heap? In theory, it can use all the space occupied by the system in addition to memory space outside. Actually be smaller than this, such as we usually opens such as QQ, browser software like, but enough to use in the general case. When it comes to second experiment, the address of a stack variable can not be returned by the function's return value, if we need to return to a variable defined within a function address how to do? We can do this:

Copy the code
// Experiment 5: 
#include "stdafx.h" #include "stdlib.h" int *getx() { int * p = (int *) malloc (sizeof (int)); // the application of a heap
return p; } int _tmain(int argc, _TCHAR* argv[]) { int * p = GetX (); *pp = 10; free(pp); }
Copy the code

  Such writing is no problem, can function returns a heap address, but we must remember that with the release of the application heap memory function through free space . "int * p = (int * ) malloc (sizeof (int));" into "static int a = 0" is legitimate. Because static memory area are valid for the entire duration of the program is running, but behind the free function can not be used!

  For application in the heap memory space also functions calloc and realloc, and usage is similar to malloc.

 Third, case studies

Case number one

 Part as follows:

  UpdateCounter part and the main function of the code, it is stored in the code area

  The default is a global array of variables, it is stored in a static area

  The main function "char * b = NULL" defines automatic variable b (variable), so the region is stored in the stack

  Then "b = (char *) malloc (1024 * sizeof (char));" applied to the stack portion of memory space, so that this space in the heap area

Case II

  Note the following:

  • The stack is increased from higher addresses to lower addresses;
  • In the C language, Drawing The function parameter is from right to left, so the function of three parameters UpdateCounter stack order of A1, C, B ;
  • Between the C language and parameter arguments are passed by value, UpdateCounter function parameters within a [1], c, b and a static area a [1], c, b is not the same ;

  "Char * b = NULL" defines a pointer variable b, b to address 0xFFF8, is empty -> Run to "b = (char *) malloc (1024 * sizeof (char))" in the stack when the application a piece of memory (assuming that memory address 0x77a0080) gave b, b at this time is the address does not change, but its value becomes the 0x77a0080, this value points to the address space of a heap (stack variables point to the value of the heap space ), the b memory process changes as follows:

                                      ---------->

Fourth, the purpose of learning memory management

  Memory management is learning to know how to manage our future memory at the right time. So the question is? When the stack with a heap when to use it? Generally follow the following three principles:

  • If you know exactly how much memory footprint data, then the amount of data is small with a stack when using larger heap;
  • If you do not know the amount of data (it may take up more memory), preferably with a heap (such as some insurance);
  • If you need to dynamically create an array, use the heap.
Copy the code
// Experiment Six: Create a dynamic array of 
int _tmain (int argc, _TCHAR * argv []) { int i; scanf("%d", &i); int *array = (int *)malloc(sizeof(int) * i); //...// here doing other operations on the array dynamically created free(array); }
Copy the code

last of the last 

  When the operating system memory management, the smallest unit is not byte, but the memory page (32-bit operating system's memory page typically 4K). For example, the initial application 1K of memory, the operating system will allocate a memory page is 4K memory. 4K is a compromise choice because: the larger memory pages, the more memory is wasted, but high operating system memory scheduling efficiency, without frequent memory allocation and release; smaller memory page, the less memory is wasted, but the operating system memory scheduling inefficient, requiring frequent allocate and free memory . Embedded system memory memory resources are scarce, its memory pages will be smaller, and therefore require special attention in the embedded under development.

Guess you like

Origin www.cnblogs.com/sea520/p/12618594.html