Memory distribution
1, Dynamic memory management in C language: malloc/calloc/realloc and free
1.malloc:
Obtain the memory space of the specified byte from the heap. The function declaration: void *malloc (int n);
If the function is executed successfully, malloc returns the first address of the obtained memory space; If the function fails, the return value is NULL.
The heap memory obtained by malloc function must be initialized with memset function.
char *str = (char*) malloc(100); assert(str != nullptr);
2.calloc:
Similar to malloc, the function declaration is void *calloc(int n, int size)// Application space = n*size
After successful execution, obtain the byte space of size * n from the heap and return the first address of the space. The execution failed and the function returned NULL.
The memory space obtained by the calloc function is initialized, and its contents are all 0.
3.realloc
The functions are richer than the first two, which can realize memory allocation and memory release. Function declaration: void * realloc(void * p,int n);
Where, the pointer p must be a pointer to the heap memory space, that is, a pointer to the space allocated by the malloc function, calloc function or realloc function.
The realloc function changes the size of the memory block pointed to by the pointer p to n bytes. If n < or = the size of the space pointed to before P, the original state remains unchanged.
If n > the size of the space previously pointed to by p, the system will reallocate a memory space of N from the heap for p
At the same time, the contents of the original pointing space are copied to the new memory space in turn, and the space pointed to before p is released. The space allocated by the relloc function is also uninitialized.
4.alloca
Request memory on the stack. When the program is out of the stack, it will automatically release memory. However, it should be noted that alloca is not portable, and it is difficult to implement on a machine without a traditional stack. Alloca should not be used in programs that must be widely transplanted. C99 supports variable length arrays (Vlas), which can be used to replace alloca.
5.free void free (void * p); Free the space on the heap indicated by void pointer P. No return value
free(p); p = nullptr;
6.memset void * memset (void * p, int c, int n) ;
Return value: returns a void type pointer to the storage area p.
For the n bytes of the first address of the void pointer p, set each byte to c.
malloc/calloc/realloc differences:
Similarities:
1. They all apply for space from the heap
2. The return value needs to be null
3. User free release is required
4. The return value type is the same (void *)
5. Both require type conversion
6. Like the underlying implementation, it is necessary to open up redundant space to maintain the application space
difference:
1. Different function names and parameter types.
2.calloc will initialize the application space and initialize it to 0, while the other two will not.
3. The space requested by malloc must be initialized with memset
4.realloc is to adjust the existing space. When the first parameter is passed in NULL, it is the same as malloc
2, C + + memory management mode (new, delete)
Dynamic memory management through new and delete operators to apply for and release continuous space.
1. When new applies for space, it will call the constructor. When delete frees up space, it will call the destructor, but malloc and free will not.
2.operator new and operator delete
It is a global function provided by the system. New and delete release space by calling the operator new and noperator delete global functions at the bottom.
3. The difference between malloc / free and new/delete
Common ground: heap application, manual release
Differences: 1 Malloc and free are functions, and new and delete are operators
2. The space requested by malloc will not be initialized, but new can be initialized
3. When malloc applies for space, it needs to manually calculate the space size and pass it. new only needs to follow the space type
4. The return value of malloc is void *, which must be forcibly rotated when used. New is not required, because new is followed by the type of space
5. When malloc fails to apply for space, it returns NULL, so it must be NULL when used. New does not need to, but new needs to catch exceptions
6. When applying for custom type objects, malloc/free will only open up the space and will not call the constructor and destructor, while new will call the constructor to initialize the object after applying for the space, and delete will call the destructor to clean up the resources in the space before releasing the space
7. The efficiency of new/delete is slightly lower than that of malloc and free, because the underlying layer of new/delete encapsulates malloc/free
4. Implementation principle of new and delete
Built in type: if you are applying for a built-in type space, new and malloc, delete and free are basically similar,
The difference is that new/delete requests and releases the space of a single element, new [] and delete [] apply for continuous space, and new throws an exception when the space application fails, and malloc returns NULL
Principle of new
1. Call the operator new function to request space
2. Execute the constructor on the requested space to complete the construction of the object
Principle of delete
1. Execute the destructor in space to clean up the resources in the object
2. Call the operator delete function to free up the space of the object
Principle of new T[N]
1. Call the operator new [] function, and actually call the operator new function in operator new [] to complete the application of N object spaces
2. Execute the constructor N times on the requested space
Principle of delete []
1. Execute the destructor N times on the released object space to clean up the resources in N objects
2. Call operator delete[] to release the space, and actually call operator delete in operator delete[] to release the space.
5. Singleton mode: a class can only create one object, and the instance is shared by all program modules.
Hungry man mode: the program is loaded and initialized at the beginning, resulting in a very slow program.
Advantages: simple. Disadvantages: the process starts slowly.
Lazy mode: don't load it at the beginning, and load it when you need it.
Advantage: when you first use an instance object, you create it. The process starts without load. The startup sequence of multiple single instance instances is freely controlled.
Disadvantages: complex
6. Memory leakage
What is a memory leak?
Memory leakage refers to the situation that the program does not release resources and no longer uses memory due to negligence or error. Memory leak means that after an application allocates a certain section of memory, it loses control of the memory due to design errors, resulting in a waste of memory.
Memory leak classification:
Heap memory leak:
Heap memory refers to a piece of memory allocated through malloc/calloc/realloc/new during program execution. After it is used up, it must be released through free/delete. If it is not released, this part of space cannot be used later, and Heap Leak will be generated.
System resource leakage:
The program uses the resources allocated by the system, such as sockets, file descriptors, pipes, etc. without using the corresponding functions, resulting in a waste of system resources, seriously reducing the system efficiency and unstable system execution.
How to avoid memory leakage?
1. Preventive in advance. Such as smart pointer, etc. (managed by RAII idea or smart pointer)
2. Error checking afterwards. Such as leak detection tools.
Designing a class can only create objects on the heap. (the constructor is privatized, providing a static member function in which the creation of heap objects is completed)
class HeapOnly { public: static HeapOnly* CreateObject() { return new HeapOnly; } private: HeapOnly() {} // C++98 // 1. Only declaration, not realization. // 2. Declared private HeapOnly(const HeapOnly&); // or // C++11 HeapOnly(const HeapOnly&) = delete; };
When designing a class, you can only create objects on the stack.
class StackOnly { public: static StackOnly CreateObject() { return StackOnly(); } private: StackOnly() {} };
Three. Template junior
1. Function template and its instantiation
template<typename T1, typename T2,......,typename Tn>
Return value type function name (parameter list) {}
Implicit instantiation: compiler automatically infers types
Display instantiation: use < >
template<typename T> void Swap( T& left, T& right) { T temp = left; left = right; right = temp; }
Implicit instantiation: let the compiler deduce the actual type of template parameters according to the actual parameters
Explicit instantiation: specify the actual type of the template parameter in < > after the function name (if it does not match, implicit type conversion will be performed)
Matching rules for template parameters:
1. A non template function can exist simultaneously with a function template with the same name, and the function template can also be instantiated as the non template function.
2. For non template functions and function templates with the same name, if other conditions are the same, non template functions will be called preferentially during transfer. If the template can produce a function with a better match, the template will be selected.
3. Template functions do not allow automatic type conversion, but ordinary functions can perform automatic type conversion
2. Class template and its instantiation:
template<class T1, class T2, ..., class Tn> class Class template name { // Intra class member definition };
Priority principle: choose who is more like me.
4, STL (an important part of C + + standard library, including software framework of data structure and algorithm)
1. Six components of STL
2. Common interfaces of string class
string() Construct empty string Class object, empty string string(const char* s) use C-sting Construct class object string(size_t n,char c) string Class object contains n Characters c string(const string&s) copy constructor string(const string&s,size_t n) use s Medium n Characters to construct a new string Class object
3. Capacity interface of string class object
size_t size() const Returns the valid character length of a string size_t length() const Returns the valid character length of a string size_t capacity()const Returns the total size of the space bool empty()const If the detection string is released as an empty string, it is returned true,Otherwise return false void clear() Clear valid characters void resize (size_t n, char c) Change the number of valid characters to n Characters for extra space c fill void resize (size_t n) Change the number of valid characters to n The extra space is filled with 0 void reserve (size_t res_arg=0) Reserve space for string
4. Access operation of string class object
char& operator[] ( size_t pos ) return pos The character of the position, const string Class object call const char& operator[] ( size_t pos ) const return pos Character of position, not const string Class object call
5. Modification of string class object
void push_back(char c) Insert character after string c string& append (const char* s); Append a string after the string string& operator+=(const string& str) Append string after string str string& operator+=(const char* s) Append after string C Number string string& operator+=(char c) Append character after string c const char* c_str( )const return C Format string size_t find (char c, size_t pos = 0)const From string pos Position starts looking back for characters c,Returns the position of the character in a string size_t rfind(char c, size_t pos = npos) From string pos Position start find character forward c,Returns the position of the character in a string string substr(size_t pos = 0, size_t n = npos)const stay str Zhongcong pos Position start, intercept n Characters, and then return it
6. Use the string class to flip the string: (the code is as follows:)
#include <iostream> #include <cstdio> #include <string> #include <cstdlib> #include <algorithm> using namespace std; //Flip string class Solution{ public: string reverseString(string s){ if (s.empty())//First, judge whether the string is empty { return s; } size_t start = 0;//Defines the beginning of the valid length of a string size_t end = s.size() - 1;//Define the tail of the effective length of a string, using size-1 while (start < end){ swap(s[start], s[end]);//String exchange ++start;//Go back from the starting position --end;//Go from the back } return s; } }; int main(){ string s = "0123456789"; cout << Solution().reverseString(s) << endl; system("pause"); return 0; }
7. Find the character that appears only once for the first time in the string: (the code is as follows:)
#include <iostream> #include <cstdio> #include <string> #include <cstdlib> #include <algorithm> using namespace std; //Flip string class Solution{ public: int firstUniqchar(string s){ //Count the number of occurrences of each character int count[256] = { 0 };//Define a counter int size = s.size();//Define a valid character length for (int i = 0; i < size; ++i){ count[s[i]] += 1;//s[i] indicates the count of characters corresponding to ASCll plus 1 //Look for characters that appear only once from front to back in character order } for (int i = 0; i < size; ++i){ if (1 == count[s[i]]){//Traverse the character whose counter is 1 and return i return i;//Find the first character that appears only once //cout << s[i] << endl;// Print out all characters that appear only once } } return -1; } }; int main(){ string s = "xx1223456789"; cout << Solution().firstUniqchar (s) << endl; system("pause"); return 0; }
8. Length of the last word in the string:
int main(){ string line; while (getline(cin, line)){ size_t pos = line.rfind(' ');//rfind finds the character from the pos position and returns the position of the character cout << line.size() - pos - 1 << endl;//size the entire character length - pos, followed by the last word - 1, minus the length of the space 1 } system("pause"); return 0; }
9. Verify that a string is a palindrome:
#include <iostream> #include <cstdio> #include <string> #include <cstdlib> #include <algorithm> using namespace std; int main(){ string s;//Define STL string cin >> s;//cin input string int i = 0; int j = s.size() - 1;//Define string length for ( i , j; i < j; i++, j--){ if (s[i] != s[j]){//Use the double pointer to scan from both sides to the middle to judge whether the characters corresponding to the subscript are equal break; } } if (i<j){ cout << "No" << endl; } else{ cout << "yes" << endl; } system("pause"); return 0; }
s.size () is the length of the string, starting with 1. s.size () - 1 is the subscript of the last character, starting from 0
The find/rfind function can pass three things:
1. Characters
2. String
3. Character container
find is from the front and rfind is from the back.
10. Light copy and deep copy:
Shallow copy: also known as bit copy, it means that the compiler only copies the values in the object. If resources are managed in the object, multiple objects will share the same resource. When an object is destroyed, it will be released, while other objects do not know it and think it is still valid. When access continues, an access error will occur.
Deep copy: to solve the problem of shallow copy, each object is allocated resources independently to ensure that multiple objects will not be released for multiple times due to shared resources, resulting in program crash. Copy constructors, assignment operator overloads, and destructors must be explicitly given.
Copy on write: on the basis of shallow copy, increase the reference count method, record the number of resources used, increase the object use, and add 1 to the count. When the object is destroyed, the count will be reduced by 1, and then check whether the resource needs to be released. If the count is 1, it indicates that it is the last object, it will be released, otherwise it cannot be released.
Simulated implementation of string class:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <string> #include <cstdlib> #include <algorithm> #include <cassert> #include <vector> using namespace std; //Simulate the implementation of string class class String{ public: String(const char* str = ""){//Constructor if (nullptr == str){//1. First judge whether str is empty assert(false);//Asserts that if the program executes incorrectly, it terminates return; } _size = strlen(str);//Define str length as_ size _capacity = _size;//Definition_ Size is the size of the space_ capacity _str = new char[_capacity + 1];//New apply for a new space strcpy(_str, str);//String copy copy } String(const String& s)//copy constructor :_str(new char[s._capacity + 1])//Initialization list , _size(s._size) , _capacity(s._capacity) { strcpy(_str, s._str); } String& operator=(const String& s){//Operator overloading if (this != &s){//Determine whether this is equal to the s reference char* pstr = new char[s._capacity + 1];//New application space strcpy(pstr, s._str);//Copy data delete _str;//Before release_ str _str = pstr;//Assign the newly requested space to_ str _size = s._size; _capacity = s._capacity; } return *this; } ~String(){//Destructor, releasing resources if (_str){ delete[] _str; _str = nullptr;//str null } } //Modification of string class void PushBack(char c){//Insert str, pushback if (_size == _capacity){//Determine whether size and space are equal //reserve(_capacity * 2);// 2X space expansion _str[_size++] = c; _str[_size] = '\0'; } } void Append(size_t n, char c){//Add str string, for (size_t i = 0; i < n; ++i){ PushBack(c); } } String& operator+=(char c){//Operator overloading+= PushBack(c); return *this; } //Job implementation void Append(const char* str); String& operator+=(const char* str); void Clear(){//Clear string _size = 0; _str[_size] = '\0'; } void Swap(String& s){//String exchange swap(_str, s._str); swap(_size, s._size); swap(_capacity, s._capacity); } const char* C_str()const//Returns a C-string { return _str; } size_t Size()const { return _size; } size_t Capacity()const { return _capacity; } bool Empty()const { return 0 == _size; } size_t Find(char c, size_t pos = 0)const;//Returns the first occurrence of the character c in a string size_t Find(const char* s, size_t pos = 0)const;//Returns the first occurrence of the string s in a string String Substr(size_t pos, size_t n);//Intercept n characters of string starting from pos position String& Insert(size_t pos, char c);//Insert the character c in the pos position and return the character position String& Insert(size_t pos, const char* str);//Inserts the string str at the pos position and returns the string position String& Erase(size_t pos, size_t len);//Deletes the element at the pos position and returns the next position of the element private: friend ostream& operator<<(ostream& _cout, const String& s);//< < operator overload, friend class private: char* _str; size_t _capacity; size_t _size; }; ostream& operator<<(ostream& _cout, const String& s)//< < operator overload { cout << s._str; return _cout; } int main(){ string s1;//Define STL string string s2("hello bit"); string s3(s2); s1 = s3; cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; system("pause"); return 0; }