Hundred battles c++ (2)

The real difference between delete and delete []

  1. delete corresponds to new delete[] corresponds to new[]
  2. For simple types, including arrays of simple types, delete is no different from delete[]. For custom type arrays, delete will only delete one element, and delete will delete all elements.

The difference between pointers and arrays

 

What is a wild pointer

A wild pointer is a pointer to a deleted object or unapplied access to a restricted memory area

Could you please answer why the destructor must be a virtual function? Why is the C++ default destructor not a virtual function 

Setting the destructor of the parent class that may be inherited as a virtual function can ensure that when we create a new subclass, and then use the base class pointer to point to the subclass object, the space of the subclass can be released when the base class pointer is released. Prevent memory leaks. If you do not set the base class pointer can only access non-inherited members.

C++' s default destructor is not a virtual function because virtual functions require additional virtual function tables and virtual table pointers, which occupy additional memory. For classes that will not be inherited, if their destructors are virtual functions, memory will be wasted. Therefore, the default destructor of C++ is not a virtual function, but is set to a virtual function only when it needs to be used as a parent class.

Please tell me about the role of the destructor in C++

The destructor corresponds to the constructor. When the object ends its life cycle, for example, when the function of the object has been called, the system will automatically execute the destructor.

The name of the destructor should also be the same as the name of the class, just add a negation symbol ~ in front of the function name , such as ~stud( ) , to distinguish it from the constructor. It cannot take any parameters and has no return value (including void type). There can be only one destructor and it cannot be overloaded.

If the user does not write a destructor, the compilation system will automatically generate a default destructor (even if the destructor is customized, the compiler will always synthesize a destructor for us, and if the destructor is customized function, the compiler will call the custom destructor before calling the synthesized destructor), it does not do anything. So many simple classes don't use explicit destructors.

If there are pointers in a class and memory is dynamically allocated during use, it is best to show that the constructor and destructor release the allocated memory space before destroying the class to avoid memory leaks.

The order of class destruction: 1 ) the destructor of the derived class itself; 2 ) the object member destructor; 3 ) the base class destructor.

Please tell me the difference between static function and virtual function

Static functions have been determined to run when they are compiled, and virtual functions are dynamically bound when they are run. Because the virtual function uses the virtual function table mechanism, it will increase the memory overhead once when it is called.

What is the difference between the following four lines of code? const char * arr = "123"; char * brr = "123"; const char crr[] = "123"; char drr[] = "123";

const char * arr = "123";

// The string 123 is stored in the constant area. const originally modifies the value pointed to by arr and cannot be modified by arr , but the string "123" is in the constant area and cannot be changed, so the effect of adding const is the same

char * brr = "123";

// The string 123 is stored in the constant area, the arr pointer points to the same location, and the value of "123" cannot be modified through brr

const char crr[] = "123";

// Here 123 is originally on the stack, but the compiler may do some optimizations and put it in the constant area

char drr[] = "123";

// The string 123 is saved in the stack area and can be modified by drr

Please answer what is the difference between new/delete and malloc/free

First of all, new/delete is a keyword of C++ , and malloc/free is a library function of C language. The latter must specify the size of the requested memory space. For objects of class type, the latter will not call constructors and destructors .

Could you please tell me how C++ handles the return value?

Create a temporary variable and pass its reference into the function as a function parameter.

Please talk about select fork, wait, exec function

The parent process generates a child process and uses fork to copy a copy of the parent process. At this time, only the page table of the parent process is copied. Both processes read the same memory. When a process writes, it uses the realistic copy mechanism to allocate memory. The exec function An elf file can be loaded to replace the parent process. From then on, the parent process and the child process can run different programs. fork returns the pid of the child process from the parent process , and returns 0 from the child process. The parent process that calls wait will block until the status of the child process changes. The execution returns 0 successfully , and returns -1 on error . If the exec executes successfully, the child process will start running from a new program, and there will be no return value, and -1 will be returned if the execution fails

Please tell me what is the difference between map and set, and how are they implemented?

Both map and set are C++ associative containers, and their underlying implementations are red-black trees ( RB-Tree ). Since the various operation interfaces opened by map and set are also provided by RB-tree , almost all the operation behaviors of map and set are just to transfer the operation behavior of RB-tree .

The difference between map and set is:

( 1 ) The elements in the map are key-value (keyword - value) pairs: the key acts as an index, and the value represents the data associated with the index; in contrast, Set is a simple collection of keywords, and in set Each element contains exactly one keyword.

( 2 ) The iterator of the set is const , and the value of the element is not allowed to be modified; the value of the map is allowed to be modified , but the key is not allowed to be modified . The reason is that map and set are sorted according to the keywords to ensure their order. If the key is allowed to be modified, then the key needs to be deleted first, then the balance should be adjusted, and then the modified key value should be inserted to adjust the balance. Come on, the structure of map and set is severely damaged , causing the iterator to fail. I don't know whether it should point to the position before the change or the position after the change. Therefore, in the STL , the iterator of the set is set to const , and the value of the iterator is not allowed to be modified; while the iterator of the map is not allowed to modify the key value, but the value value is allowed to be modified .

( 3 ) map supports subscript operation, but set does not support subscript operation. The map can use the key as a subscript. The subscript operator [ ] of the map uses the key as a subscript to perform a search. If the key does not exist, an element with the key and the default value of the mapped_type type is inserted into the map . Therefore, the subscript operator [ ] needs to be used with caution in map applications . It cannot be used with const_map . It should not be used when you only want to determine whether a certain key value exists but does not want to insert elements. The mapped_type type has no default value and should not be used. If find can solve the need, use find as much as possible .

The underlying structure of unordered map is a hash table

 Please talk about the difference between vector and list, the application, the more detailed the better

1. Concept:

1Vector

Continuously stored containers, dynamic arrays, allocate space on the heap

Underlying implementation: array

Double capacity increase:

When adding (inserting) a new element to the vector , if it does not exceed the capacity at that time, there is still room left, then add it directly to the end (insert at the specified position), and then adjust the iterator.

If there is no space left, it will reconfigure the space twice the number of original elements, then initialize the new space by copying the elements of the original space, add elements to the new space, and finally destroy and release the original space. Iterators will be invalidated.

performance:

Access: O(1)

Insert: insert at the end (enough space): soon

Insert at the end (insufficient space): Memory application and release are required, as well as copying of previous data.

Insert in the middle (enough space): memory copy

Insert in the middle (insufficient space): memory application and release, and copying of previous data are required.

delete: at the end delete: soon

delete in the middle: memory copy

Applicable scenarios: frequent random access, and infrequent insertion and deletion of non-tail nodes.

2List

The dynamic linked list allocates space on the heap. Space is allocated every time an element is inserted, and space is released every time an element is deleted.

Bottom layer: doubly linked list

performance:

Access: The performance of random access is very poor, and only the head and tail nodes can be accessed quickly.

Insertion: fast, generally constant overhead

delete: fast, generally constant overhead

Applicable scenarios: frequent insertion and deletion of large amounts of data

2. Difference:

1 ) The underlying implementation of vector is an array; list is a doubly linked list.

2 ) vector supports random access, but list does not.

3 ) vector is sequential memory, list is not.

4 ) The insertion and deletion of vector in the middle node will cause memory copy, but the list will not.

5 ) The vector allocates the memory at one time, and expands the capacity by 2 times when it is not enough ; the list will apply for memory every time a new node is inserted.

6 ) Vector has good random access performance but poor insertion and deletion performance; list has poor random access performance and good insertion and deletion performance.

3. Application

Vector has a continuous memory space, so it supports random access. If you need efficient random access and don't care about the efficiency of insertion and deletion, use vector .

List has a discontinuous memory space. If you need efficient insertion and deletion, and don't care about random access, you should use list .

Please tell me about the role of iterators in STL, why do you need iterators if you have pointers?

1. Iterator

Iterator (iterator) mode, also known as Cursor (cursor) mode, is used to provide a method to sequentially access each element in an aggregate object without exposing the internal representation of the object. Or it may be easier to understand in this way: Iterator mode is a mode applied to aggregated objects. By using this mode, we can access aggregates in a certain order (method provided by iterator ) without knowing the internal representation of the object. individual elements of the object.

Due to the above characteristics of the Iterator mode: coupling with aggregate objects, its wide application is limited to a certain extent, and it is generally only used for underlying aggregation support classes, such as STL list , vector , stack and other container classes and extended iterators such as ostream_iterator .

2. The difference between iterators and pointers

Iterators are not pointers, but class templates that behave like pointers. He just simulates some functions of pointers, by overloading some operators of pointers, -> , * , ++ , -- and so on. The iterator encapsulates the pointer and is an object that can traverse all or part of the elements in the STL ( Standard Template Library ) container . Advanced behavior is equivalent to a smart pointer, which can implement different ++ , -- and other operations according to different types of data structures. 

The iterator returns the object reference rather than the value of the object, so cout can only output the value after the iterator uses * to get the value and cannot directly output itself.

3. The reason for the generation of the iterator

The access method of the Iterator class is to abstract the access logic of different collection classes, so that the effect of looping through the collection can be achieved without exposing the internal structure of the collection.

Please answer the difference between resize and reserve in STL

resize() : change the number of elements contained in the current container (size()) , eg: vector<int>v; v.resize(len); the size of v becomes len, if the original size of v is less than len , then the container Add ( len-size ) elements, and the value of the element is 0 by default. When v.push_back(3); After that, 3 is placed at the end of v , that is, the subscript is len , and the container is size at this time It is len+1 ; reserve() : Change the maximum capacity of the current container ( capacity ) , it will not generate elements, it just determines how many objects are allowed to be placed in this container, if the value of reserve(len) is greater than the current capacity() , then Will reallocate a block that can store len
object space, and then copy the previous v.size() objects through the copy constructor , and destroy the previous memory;

left and right values

In C++11 , those that can take addresses and have names are lvalues. Conversely, those that cannot take addresses and have no names are rvalues ​​(xvalues ​​or prvalues).

A const lvalue reference extends the lifetime of an rvalue.

 

Guess you like

Origin blog.csdn.net/hebtu666/article/details/127204643