A brief analysis of the difference between new and malloc and memory allocation

Source: Internet
Author: User
Tags function prototype int size

Original address: http://www.cnblogs.com/huhuuu/p/3432371.html

As you can see from the function declaration. malloc and new are at least two different: new returns a pointer of the specified type and can automatically calculate the required size. Like what:

int *p;
p = new int; 
The return type is the int* type (integer pointer) and the allocation size is sizeof (int);

Or:

Int* Parr;
Parr = new int [m]; 
The return type is the int* type (integer pointer), and the allocation size is sizeof (int) * 100;

malloc, however, must compute the number of bytes by us and forcibly convert to a pointer of the actual type upon return.

int* p;
p = (int *) malloc (sizeof (int) *128);
Allocate 128 integer storage units (which can be replaced by the actual need),
//and store the first address of the 128 consecutive integer storage units in the pointer variable p
double *pd= (double *) malloc (double) *12);
Allocate 12 double storage units,
//and store the first address in the pointer variable PD
The first, malloc function returns a void * type. For C + +, if you write: p = malloc (sizeof (int)); The program cannot compile and error: "Cannot assign void* to int * type variable". So you must pass the cast by (int *). And for C, there is no such requirement, but in order to make the C program more convenient porting to C + +, it is recommended to develop the habit of forced conversion. Second, the function's argument is sizeof (int), which indicates the size required for an integer data. If you write:
int* p = (int *) malloc (1);

Code can be compiled, but in fact allocates only 1 bytes of memory space, when you deposit an integer, there will be 3 bytes homeless, and directly "live in the neighborhood." The result is that the original data content in later memory is overwritten.

The principle of the following passage is quite clear . The substance of the malloc function now, it has a so-called free list that connects the available chunks of memory to a long listing. When the malloc function is invoked, it looks for a block of memory that is large enough to meet the user's request in the join table. The memory block is then split in half (the size of the piece is equal to the size of the user request, and the other is the remaining byte). Next, the memory assigned to the user is passed to the user, and the remaining piece, if any, is returned to the connection table. When the free function is invoked, it connects the memory blocks freed by the user to the idle chain. In the end, the free chain will be cut into a lot of small memory fragments, if the user requests a large memory fragment, then the idle chain may not be able to meet the user requirements of the fragment. As a result, the MALLOC function requests a delay and begins to rummage through the free chain to check each memory fragment, organize them, and merge the adjacent small free blocks into larger chunks of memory. If the required memory block is not available, the malloc function returns a null pointer, so be sure to make a return value when invoking the malloc dynamic request memory block.

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: program code:
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: program code:
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)

   OK. 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. Program code:
   // 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.

Partially reprinted from http://www.bccn.net/Article/kfyy/cyy/jszl/200608/4238_2.html

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.