In c language learning, the memory management part of the knowledge of the master is particularly important. The previous malloc () and free () two functions in C are very poorly understood, only know how to use it-that is malloc and then free is all OK. Of course, the two functions of the current experience is not much, but for the third part of this article has a turning point of understanding, so
Write down this article as a summary of knowledge. This article is named in a "talk" of the word, that is the meaning of this. I hope to help you a little.
If it's not too far away (such as how virtual memory and physical memory in the operating system are managed, etc.), I feel that this article should be a more comprehensive talk about malloc () and free (). This article introduces the main content in three parts.
So much nonsense, the following immediately into the subject of the ================ "" "", "" "", "" "" "" "" "," "" The "" "", "the" "",
Basic concepts and basic usage of malloc () and free ():
1, function prototype and description:
void *malloc (Long numbytes): The function allocates numbytes bytes and returns a pointer to the memory. If the allocation fails, an empty pointer (NULL) is returned.
There should be a variety of reasons for allocation failure, such as lack of space.
void free (void *firstbyte): The function is to return the space previously allocated by malloc to the program or the operating system, that is, to release the memory and let it regain its freedom.
2, the use of the function:
In fact, these two functions are not very difficult to use, that is, malloc () after the use of enough to throw it to free (), for a simple example:
Code ...
char *ptr = NULL;
PTR = (char *) malloc (* sizeof (char));
if (NULL = = Ptr)
{
Exit (1);
}
Gets (PTR);
Code ...
Free (PTR);
PTR = NULL;
Code ...
That's it. Of course, the specific situation to be specific analysis and specific solutions. For example, if you define a pointer, apply a piece of memory in a function and pass it back through the function, then perhaps the work of freeing this memory should be left to other functions.
3, about the use of functions need to pay attention to some places:
A, after you have applied for the memory space, you must check whether the assignment is successful.
B, when you do not need to use the memory of the application, remember to release, after the release should point to the memory pointer to null, to prevent the program behind the careless use of it.
C, these two functions should be paired. If the application is not released after the memory leak, if no reason to release that is nothing to do. Release only once, if released two times and more than two times will
Error (free null pointer exception, free null pointer is actually equal to nothing, so freeing the null pointer to release how many times there is no problem).
D, although the type of the malloc () function is (void *), any type of pointer can be converted to (void *), but it is preferable to force the type conversion in front of it, because it can escape a
Some of the compiler checks.
All right. The most basic thing to say about that. Now go to Part two:
Second, malloc () from where to get the memory space:
1, malloc () from where to get the memory space. The answer is to get space from the heap. That is, the function returns a pointer to a piece of memory inside the heap. There is a linked list in the operating system that records the free memory address. When the operating system receives the application, it traverses the list, then looks for the first heap node that is larger than the requested space, and then deletes the node from the Free node list and assigns the node space to the program. That's it.
Here, I have to insert a small topic, I believe we also know what the topic. What is the heap. When it comes to heaps, I can't help talking about stacks. What is a stack. Here are a few other special and simple to say this topic aside:
2, what is the heap: The heap is a common space, divided into global heap and local heap. The global heap is all space that is not allocated, and the local heap is the space that the user allocates. The heap is allocated during the initialization of the process by the operating system, and can be added to the system during the run, but remember to return it to the operating system or memory leak.
What is stack: The stack is unique to the thread, saving its running state and local automatic variables. The stack is initialized when the thread starts, and each thread's stack is independent of each other. Each function has its own stack, which is used to pass arguments between functions. The operating system will automatically switch the stack when switching threads, which is to switch SS/ESP registers. Stack space does not need to be explicitly allocated and released within a high-level language.
The above concept description is a standard description, but there are individual statements deleted by me, do not know because of this and become non-standard ^_^.
Through the description of the concept above, you can know:
Stack is automatically allocated by the compiler release, the function of the value of the parameters, local variables, and so on. The operation is similar to the stack in the data structure.
The heap is typically freed by the programmer and, if not freed, may be reclaimed by the OS at the end of the program. Note that this is possible, not necessarily. So I want to stress again, remember to release.
Note that it is different from the heap in the data structure, and the distribution is similar to the linked list. (I've mentioned this a little bit above)
So, for example, if you define a pointer variable on a function, you then apply a piece of memory in the function to let the pointer point to it. In fact, the address of this pointer is on the stack, but it is pointing to a heap of content. This point should be noted. So, think again, after you've applied for space in a function, say the following function:
Code ...
void Function (void)
{
Char *p = (char *) malloc (* sizeof (char));
}
In this example, do not think that the function returned, the function of the stack is destroyed the pointer is also destroyed, the application of memory is also destroyed. This is absolutely wrong. Because the application memory is on the heap, and the stack of the function is destroyed, it has nothing to do with the heap. So, it's still the same sentence: remember to release.
3, Free () in the end released what
This question is relatively simple, in fact, I would like to and the second most of the topic echoes. Ha ha. Free () frees the memory that the pointer points to. Attention. The memory is freed, not the pointer. This is very, very important. The pointer is a variable that is destroyed only when the program ends. After freeing up the memory space, the pointer to the space is still present. But now the pointer points to the content of the garbage, is undefined, so that is rubbish. So, as I said earlier, when you release the memory, point the pointer to null to prevent the pointer from accidentally being referenced later. Very important AH this.
All right. This "digression" finally finished. Just say it one more time, and you'll get a ballpark figure. Here we go to the third part:
Three, malloc () and free () mechanism:
I have a new understanding of this part today. And it's a turning point of understanding. So, there may be some more misconceptions about this part. The wrong place please help point out.
In fact, a closer look at the function prototype of free () may also be found to be very magical, the free () function is very simple, only one parameter, as long as the pointer to the application space passed
The parameters in free () allow you to complete the release work. This is where the malloc () application problem is traced. The application actually takes up more memory than the application. Because the excess space is used to record the management information on this block of memory. Take a look at the seventh chapter of Advanced Programming in UNIX environment:
Most implementations allocate more storage space than is required, and additional space is used to record management information-the length of the allocation block, the pointer to the next allocation block, and so on. This means that if you write the end of an allocated area, you will overwrite the latter piece of management information. This type of error is catastrophic, but it's hard to find because it's not going to be exposed very quickly. Moving the pointer back to the allocation block may overwrite the management information for this block.
The above passage has given us some information. malloc () Application of the space is actually I think that is divided into two different types of space. One is the space to record management information, and the other is the available space. And the information that is used to record management is actually a structural body. In C language, the different information of the same object is recorded by the structure body.
The natural thing. Here's a look at the prototype of this structure:
struct Mem_control_block {
int is_available; This is a marker.
int size; This is the size of the actual space
};
For size, this is the actual space size. Here in fact I have a question, whether Is_available is a mark. Because I looked at the source code of free () and felt a little puzzled about the variable (the source is analyzed below). Please also point out here.
Therefore, free () is based on the structure of information to release the malloc () application space. And the size of the two members of the structure I think it should be the operating system. But here's the problem, malloc () to return a pointer to a second space, or free space, after the application space. Otherwise, if you point to the management information space, the contents of the write and the type of the structure may be inconsistent, or the management information will be blocked off, it can not free memory space, so there will be errors. (I feel like I'm talking nonsense here)
All right. Below look at the source code of free (), I analyzed for a moment, feel compared to malloc () The source is easy a lot easier. Just a question, as noted below.
Code ...
void free (void *ptr)
{
struct Mem_control_block *free;
free = ptr-sizeof (struct mem_control_block);
free->is_available = 1;
Return
}
Look at the second sentence of the function, this sentence is very important and key. In fact, this sentence is to point to the free space of the pointer back, let it point to the management of the information of the space, because here is the value of subtracting a struct size. The latter sentence free->is_available = 1; I'm a little puzzled. My idea is: here the is_available should be just a mark. Because from the name of this variable, is_available translation is "can be used." Don't say I'm dirt. I think variable names can reflect the role of a variable, especially the rigorous code. This is the source code, so I think it is absolutely rigorous. The value of this variable is 1, which indicates that it is a space that can be used. Just here I think, if I change it to 0 or something else, I don't know what's going to happen. But one thing I can be sure of is that the release is never going to go so smoothly. Because this is a marker.
Of course, there may be some doubt here, why this can be released. I have the same question just now. Then I thought, release is the operating system, then the free () the source code to see that nothing has been released, right. But it does determine the content of the memory that manages the information. So, free () Just records some information, and then tells the operating system that memory can be released, specifically how to tell the operating system I do not know, but I think this is beyond the scope of my discussion of this article.
Well, I had the mistaken belief that a pointer to that memory could release that memory regardless of where it was moved into that block of memory. But this is a big mistake. Release is not a part of the release. The first point should be understood. Also, from the source Code of free (), PTR can only point to the first address of the available space, otherwise, subtracting the structure size must not be the first address to the management information space. So, make sure the pointer points to the first address of the free space. Don't believe it. You can write a program and then move a pointer to the available space to see if the program will collapse.
Finally, you may think of malloc () source code to see malloc () In the end is how to allocate space, which involves a lot of other aspects of knowledge. Interested friends can go to download the source themselves
Code to see.