C ++-memory allocation, construction, and analysis of various objects in the object model

Source: Internet
Author: User

Processing of internal data types is as follows: global variables and arrays are allocated to data segments before the main function is executed, and the memory is reclaimed by the system after the program ends; local static variables and arrays are allocated to the data segment when the program runs for the first time. After the program ends, the memory is reclaimed by the system. The data generated by malloc is allocated to the heap. If the program needs to be released, you must manually call free. If the program is not released, the memory is reclaimed by the system. For internal data types, the array and common variables are no different. However, for class objects, in addition to allocating and releasing the corresponding memory, you also need to call constructor and destructor, so class objects cannot be exactly the same as internal data type processing. The following sections describe several situations separately. Note that all these lei have at least constructors, destructor, or both. Otherwise, the allocation of class objects is the same as the allocation of internal data type variables. Partial object 1. local objects are allocated memory on the stack just like internal data type variables; 2. at least before using this object, call the object's constructor to construct it; 3. call the object's destructor in all the places where the function leaves (before return). Therefore, if class objects are defined at the beginning of the function, there may be multiple places to call the destructor, this will increase the amount of code. Therefore, unlike C Programs that define variables at the beginning, it is recommended that C ++ programs define class objects nearby for use, which may reduce the number of calls to the destructor. Global Object 1. the memory of the global object will be allocated to the data segment before main; 2. each object corresponds to a _ sti () function, which calls the constructor. Then, all the global object's _ sti () functions are executed at the beginning of the main function, this is called static initialization; 3. correspondingly, every _ std () function calls the destructor. All the _ std () functions are executed at the last position of main. The most difficult part of a local static object is that the object can only be constructed once, that is, the constructor can only execute once. We naturally have to think of setting a global identifier for each local static object. If the identifier meets any criteria, it indicates that it has not been constructed. If the identifier meets any criteria, it indicates that it has been constructed. This flag can be bool or a pointer to a static object (if not constructed, the pointer is NULL, and after being constructed, it is an address ). In this case, the identifier is changed to false or NULL. The object array needs to be constructed once for each element of the array. the compiler will generate a vec_new function or its variants to construct these elements. The function may be as follows: void * vec_new (void * array, size_t elem_size, int elem_count, void (* constructor) (void *), void (* destructor) (void *)). Of course, vec_new will not be called when the class has no constructor or destructor. If the array is global, It will be executed at the beginning of the main function. If it is local, it will be called during memory allocation. If it is local static, it will be called during the first call. However, to declare an object as an array, you must ensure that the object does not have a constructor, a default construtor, or a constructor with a default parameter. Therefore, assume that the constructor has a default parameter, so how are these parameters assigned by calling constructor? Obviously, vec_new cannot. Therefore, based on this situation, the compiler generates a function called stub constructor. Assume that the class name class1 has the following structure: class1: class1 () {class1 (default parameter list );} this is against the C ++ syntax. You can try to write a non-parameter constructor and a constructor with default parameters, which cannot be compiled. Remember, this is a special case. New object new, as the C ++ operator, will be processed as code similar to the following logic during compilation, for example: Class1 * p = new Class1 (); will be processed: p = _ new (sizeof (Class1); if (p! = NULL) p = Class1: Class1 (p); first allocates memory on the heap through _ new, and then calls the constructor if the allocation is successful. Do you still remember why the size of an empty class is also 1? To ensure that the object addresses of the two empty classes are different, when sizeof (Class1) is 0, the _ new function allocates 1 byte of memory to p. Similarly, delete p is processed as follows: if (p! = NULL) _ delete (p); _ new and _ delete are implemented? Although there are no hard rules, they are generally implemented using standard malloc and free functions. The main difficulty of the new array object for array objects is how to know the total number of objects in the array When deleting the array. Let's take a look at what new [] has done. New [] first allocates memory, and then calls the vec_new function to construct each element like the object array. The difference is that the first parameter of the vec_new function called by new [] is 0, tells the system to allocate resources on the stack. This is actually the difference from the object array. The difficulty lies in the large difference between delete [] and delete. How can we know the dimension of an array When deleting an array object? I currently know two ways: method 1. add a word memory record, which is described in Objective C ++. Add this record at the beginning of the array. method 2. an additional "Union array" is maintained to save the address of all arrays in the process and the dimension of the array. Some compilers may add other information, such as the destructor address. If you do not maintain the destructor address to save memory, you must understand the destructor address during the delete operation. The destructor address is determined by the p object type of delete p, but an error occurs when base * p = new derived [10, when you delete [] p, the called destructor will be the destructor of the base. Therefore, to ensure that the destructor of the derived is called correctly, it is best not to change the type pointed by the p pointer. My question 1. is it difficult to know the number of elements? In c Programming, we allocate and release the memory, which is malloc and free. malloc will specify the length of memory to be allocated, but when it is free, given the correct memory start address, you can release the correct Memory Length. This clearly utilizes the memory management mechanism of the operating system. Then, new [] actually calls malloc for allocation at the underlying layer, and calls free at delete. It is easy to know the Memory Length allocated at new []. The length is divided by the size of an object, you can get the number of objects. Therefore, further research is needed to solve this problem. Some mechanisms are certainly not clear, and the number of elements is not so easy to understand. The placement new object re-allocates an object on an existing block of memory. Therefore, we naturally require that this memory be able to store this object. Placement new has two steps: 1. change the memory type Class1 * p = new (existting_mem) Class1; 2. execute the constructor. FAQ 1. if you execute p = new (existting_mem) Class1 twice in a row, you should execute the class1 destructor for the second execution. For such problems, this problem can only be avoided by programmers themselves. C ++ does not provide a 10 thousand strategy; 2. base B; new (& B) Derived; assume that both the Base and Derived classes declare virtual f (), then B. f () executes Base or Derived. Unfortunately, the compiler generally calls Base: f (). It is relatively simple to use placement new, so pay attention to it when using it. Temporary objects such as www.2cto. comClass1 A, B; if (A + B) {// do something;} A + B will generate A temporary object, if then judge the temporary object. The C ++ standard does not provide clear rules on how the temporary object is released. A temporary object is generally invisible to programmers. It is automatically generated by the compiler, which may cause efficiency problems. As for how to avoid efficiency problems, it depends on time.

Related Article

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.