Dynamic memory management
Apply for memory by creating variables When memory is released depends on what kind of variable the variable is
If it is a global variable, it will be released following the program
If it is a static variable, it is also released with the program
If it is a local variable, it is released following the code block
1. Dynamic memory management can more flexibly determine the application time and release time~
2. Dynamic memory management can determine the size of memory application at run time~
malloc
void* malloc (size_t size); //size is the number of bytes. The compiler only knows the starting address of memory, //Do not know the size, apply for continuous memory, //Under normal circumstances, check whether the application is successful (NULL if unsuccessful)
use
#include<Windows.h> #include<stdio.h> #include<stdlib.h> int main(){ int* p = (int*)malloc(4); *p = 10; printf("%d\n", *p); //Understand these 40 bytes as an int array with a length of 10 elements // p is the starting element address of the array int* p = (int*)malloc(10 * sizeof(int)); for (int i = 0; i < 10; i++) { p[i] = 0; } system("pause"); return 0; }
Release time
1. If the program finishes running, it will be released together with the program
2. When the program is not finished, call free manually, and it will be released
free
void free (void* ptr);//The address returned by ptr maolloc can handle NULL
use
#include<Windows.h> #include<stdio.h> #include<stdlib.h> int main(){ //Understand these 40 bytes as an int array with a length of 10 elements // p is the starting element address of the array int* p = (int*)malloc(10 * sizeof(int)); for (int i = 0; i < 10; i++) { p[i] = 0; } free(p); system("pause"); return 0; }
The introduction of "smart pointer" in C + + can solve the problem of memory leakage to a certain extent. Using the RAlI mechanism ~ in C + + can execute some logic before the function exits
You can put the free operation into such logic~
Java / Python, with the introduction of garbage collection mechanism, can better solve the problem of memory leakage
Memory recycling does not need to be manually recycled by the program, but there is special logic inside the program to scan regularly to see which memory can be released at present, and then it will be released automatically
calloc
void* calloc (size_t num, size_t size);
use
#include <stdio.h> #include <stdlib.h> int main() { int *p = (int*)calloc(10, sizeof(int)); if(NULL != p) { //Use space } free(p); p = NULL; return 0; }
The memory requested by calloc will be initialized to all 0
The memory requested by malloc will not be initialized, and the values in memory are random values
realloc
When realloc expands, it also depends on whether there is enough free space in the back. If there is enough space in the back, you can directly break through the wall and make direct use of the space in the back
If there is not enough space in the back, just find a larger space and move it as a whole~
void* realloc (void* ptr, size_t size);
use
#include <stdio.h> int main() { int *ptr = (int*)malloc(100); if(ptr != NULL) { //Business processing } else { exit(EXIT_FAILURE); } //Expansion capacity //Code 1 ptr = (int*)realloc(ptr, 1000);//Is this ok? (what happens if the application fails?) //Code 2 int*p = NULL; p = realloc(ptr, 1000); if(p != NULL) { ptr = p; } //Business processing free(ptr); return 0; }
Common memory errors
void test() { int *p = (int *)malloc(INT_MAX/4); *p = 20;//If the value of p is NULL, there is a problem free(p); } void test() { int i = 0; int *p = (int *)malloc(10*sizeof(int)); if(NULL == p) { exit(EXIT_FAILURE); } for(i=0; i<=10; i++) { *(p+i) = i;//Cross border access when i is 10 } free(p); } void test() { int a = 10; int *p = &a; free(p);//Only dynamically requested memory is released } void test() { int *p = (int *)malloc(100); p++; free(p);//p no longer points to the beginning of dynamic memory } void test() { int *p = (int *)malloc(100); free(p); free(p);//Repeated release } void test() { int *p = (int *)malloc(100); if(NULL != p) { *p = 20; }//Memory leak } int main() { test(); while(1); }
Common question types
1.
void GetMemory(char *p) { p = (char *)malloc(100); } void Test(void) { char *str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); }
1. Memory leak malloc has no free
2. It is not determined that the return value is NULL after malloc
3. The getmemory function cannot modify the value of str. ~ STR is still NULL After strcpy, there will be a problem~
2.
char *GetMemory(void) { char p[] = "hello world";//Local variables are released as the function is released return p; } void Test(void) { char *str = NULL; str = GetMemory();//The memory referred to by the local variable has been released printf(str); }
3.
void GetMemory(char **p, int num) { *p = (char *)malloc(num); } void Test(void) { char *str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); printf(str); }
1. Memory leak malloc has no free
2. It is not determined that the return value is NULL after malloc
4.
void Test(void) { char *str = (char *) malloc(100); strcpy(str, "hello"); free(str); if(str != NULL) { strcpy(str, "world"); printf(str); } }
The memory area of a program
In linux
Stack size can be configured (generally 1m)
linux modifies the stack size
file
classification
Ordinary file: text file, binary file
Catalog file
correlation function
All io functions are in stdio Included in H
FILE structure
Used to describe a file~
The file is on disk It's not easy to operate the disk directly Therefore, the operating system is encapsulated
When you open a FILE, you actually create a variable (FILE structure variable) in memory, which is associated with the FILE on the disk Reading / writing this variable is equivalent to reading and writing files
fopen
//Open file FILE * fopen ( const char * filename, const char * mode ); //Parameter the file path of the former and the opening method of the latter
use
#define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include <stdio.h> #include <errno.h> #include <string.h> int main(){ /* fp => file pointer field name pointer NULL is returned if opening the file fails If the file does not exist or does not have read and write permissions, it will fail*/ FILE* fp = fopen("E:/test.txt", "r"); if (fp == NULL) { printf("fail to open file! Error code: %s\n", strerror(errno));//Error a macro definition represents an error system("pause"); return 0; } printf("File opened successfully! fp=%p\n", fp); system("pause"); return 0; }
strerror
Return the error code and the corresponding error information.
char * strerror ( int errnum );
use
#include <stdio.h> #include <string.h> #include <errno. h> / / header files that must be included int main () { FILE * pFile; pFile = fopen ("unexist.ent","r"); if (pFile == NULL) printf ("Error opening file unexist.ent: %s\n",strerror(errno)); //errno: Last error number return 0; }
fclose
//Close file int fclose ( FILE * stream );
use
#include <stdio.h> int main () { FILE * pFile; //Open file pFile = fopen ("myfile.txt","w"); //File operation if (pFile!=NULL) { fputs ("fopen example",pFile); //Close file fclose (pFile); } return 0; }
fread
Data reading mode: byte stream and datagram
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); //*ptr reads the memory address of the content and returns the number of successful reads
use
#define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include <stdio.h> #include <errno.h> #include <string.h> int main(){ /* fp => file pointer field name pointer NULL is returned if opening the file fails If the file does not exist or does not have read and write permissions, it will fail*/ FILE* fp = fopen("E:/test.txt", "r"); if (fp == NULL) { printf("fail to open file! Error code: %s\n", strerror(errno));//Error a macro definition represents an error system("pause"); return 0; } printf("File opened successfully! fp=%p\n", fp); char buffer[10] = "1111" ; fread(buffer, 1, 8, fp); printf(buffer); system("pause"); return 0; }
fwrite
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
use
#define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include <stdio.h> #include <errno.h> #include <string.h> int main(){ /* fp => file pointer field name pointer NULL is returned if opening the file fails If the file does not exist or does not have read and write permissions, it will fail*/ FILE* fp = fopen("E:/test.txt", "w"); if (fp == NULL) { printf("fail to open file! Error code: %s\n", strerror(errno));//Error a macro definition represents an error system("pause"); return 0; } printf("File opened successfully! fp=%p\n", fp); char buffer[10] = "1111" ; fwrite(buffer, 1, 4, fp); printf(buffer); system("pause"); return 0; }
Other sequential reading and writing
EOF
If a file has been read, and then continue to try to read, EOF will be read
EOF 'is actually - 1, not a character in ascii code table Just use - 1 to represent that the file has been read
sscanf and sprintf
//sscanf parses a content from a string //sprintf outputs a formatted result to a string char* str = "num = 10"; int num = 0; sscanf(str, "num = %d", &num); printf("%d\n", num); char str[1024] = { 0 }; sprintf(str, "num = %d", 10); printf(str); A particularly important usage://For conversion between strings and numbers (integers / floating point numbers)~ // Convert the string to an integer and use sscanf char* str1 = "10"; char* str2 = "20"; // Here I want to calculate the sum of these two values~ int num1 = 0; // At this time, the content in str1 is extracted and converted into int sscanf(str1, "%d", &num1); int num2 = 0; sscanf(str2, "%d", &num2); int result = num1 + num2; printf("result = %d\n", result); // Convert an integer to a string and use sprintf int num = 100; char buffer[1024] = { 0 }; sprintf(buffer, "%d", num); printf("%s\n", buffer);
Integer and string conversion atoi iota
#define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> /* atoi */ int main () { int i; char buffer[256]; printf("Enter a number: "); fgets(buffer, 256, stdin); i = atoi(buffer); printf("The value entered is %d. Its double is %d.\n", i, i * 2); system("pause"); return 0; } char * itoa ( int value, char * str, int base ); #define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> /* atoi */ int main () { int i; char buffer[33]; printf("Enter a number: "); scanf("%d", &i); _itoa(i, buffer, 10); printf("decimal: %s\n", buffer); _itoa(i, buffer, 16); printf("hexadecimal: %s\n", buffer); _itoa(i, buffer, 2); printf("binary: %s\n", buffer); system("pause"); return 0; }
fscanf
int fscanf ( FILE * stream, const char * format, ... );
use
/* fscanf example */ #include <stdio.h> int main () { char str [80]; float f; FILE * pFile; pFile = fopen ("myfile.txt","w+"); fprintf (pFile, "%f %s", 3.1416, "PI"); rewind (pFile); fscanf (pFile, "%f", &f); fscanf (pFile, "%s", str); fclose (pFile); printf ("I have read: %f and %s \n",f,str); return 0; }
fprintf
int fprintf ( FILE * stream, const char * format, ... );
use
#define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include <stdio.h> #include <errno.h> #include <string.h> int main(){ /* fp => file pointer field name pointer NULL is returned if opening the file fails If the file does not exist or does not have read and write permissions, it will fail*/ FILE* fp = fopen("E:/test.txt", "w"); if (fp == NULL) { printf("fail to open file! Error code: %s\n", strerror(errno));//errno a macro definition represents an error system("pause"); return 0; } printf("File opened successfully! fp=%p\n", fp); char buffer[10] = "1111" ; fprintf(fp,"jiezhe:%s",buffer); printf(buffer); system("pause"); return 0; }
// stdout is actually a variable of type FILE * This is what we call standard output // This code is equivalent to printf fprintf(stdout, "num = %d\n", 10); // Similarly, fscanf(stdin, "xxxxx"); This code is equivalent to scanf
Random reading and writing
fseek
Locate the file pointer according to the position and offset of the file pointer
int fseek ( FILE * stream, long int offset, int origin ); #include <stdio.h> int main () { FILE * pFile; pFile = fopen ( "example.txt" , "wb" ); fputs ( "This is an apple." , pFile ); fseek ( pFile , 9 , SEEK_SET ); fputs ( " sam" , pFile ); fclose ( pFile ); return 0; }
ftell
Returns the offset of the file pointer from the starting position
long int ftell ( FILE * stream ); #include <stdio.h> int main () { FILE * pFile; long size; pFile = fopen ("myfile.txt","rb"); if (pFile==NULL) perror ("Error opening file"); else { fseek (pFile, 0, SEEK_END); // non-portable size=ftell (pFile); fclose (pFile); printf ("Size of myfile.txt: %ld bytes.\n",size); } return 0; }
rewind
Returns the position of the file pointer to the starting position of the file
void rewind ( FILE * stream ); #include <stdio.h> int main () { int n; FILE * pFile; char buffer [27]; pFile = fopen ("myfile.txt","w+"); for ( n='A' ; n<='Z' ; n++) fputc ( n, pFile); rewind (pFile); fread (buffer,1,26,pFile); fclose (pFile); buffer[26]='\0'; puts (buffer); return 0; }
Determination of end of file reading
- Whether the text file reading is completed, and judge whether the return value is EOF (fgetc) or NULL (fgets)
For example:
fgetc determines whether it is EOF
fgets determines whether the return value is NULL - Judge whether the return value is less than the actual number to be read after reading the binary file.
For example:
fread determines whether the return value is less than the actual number to be read.
Refresh cache
#include <stdio.h> #include <windows.h> //VS2013 WIN10 environment test int main() { FILE*pf = fopen("test.txt", "w"); fputs("abcdef", pf);//Put the code in the output buffer first printf("Sleep for 10 seconds-The data has been written. Open it test.txt File, no content found in the file\n"); Sleep(10000); printf("refresh buffer \n"); fflush(pf);//When the buffer is refreshed, the data of the output buffer is written to the file (disk) //Note: fflush cannot be used on higher version VS printf("Sleep for another 10 seconds-At this point, open again test.txt File, the file has content\n"); Sleep(10000); fclose(pf); //Note: fclose also flushes the buffer when closing the file pf = NULL; return 0; }
Cache refresh time:
1. The buffer is full
2. fclose is closed
3. The function of fflush is to manually refresh the buffer
Pretreatment
2 the compilation process is the most important
predefined symbol
__FILE__ //Source file for compilation __LINE__ //The current line number of the file __DATE__ //Date the file was compiled __TIME__ //The time the file was compiled __STDC__ //If the compiler follows ANSI C, its value is 1, otherwise it is undefined
define
1. Define constants~
#define MAX 1000
2. Define alias for type~
#define uint unsigned int uint num = 10;
3. Customize some "Keywords"|
#define and && #define and&& #define if #define else #define loop for #define assignment= #define integer int int num = 10; if (num < 10 also num > 0) { } integer num Assignment 10; If(num < 10 also num > 0) { } otherwise { }
4. Use macros as some "compile switches" (combiner #if this series of operations)
5. Define a code fragment
#define ADD(x, y) x + y printf("%d\n", ADD(10, 20));
Macro advantages and problems
3. Macros are not recursive
4. Macro has no parameter check (it seems convenient not to write the type of the parameter, but it is actually more troublesome. The parameter has not been checked. It is unknown whether your actual parameter is passed correctly and whether it meets the requirements)|
#undef
This instruction is used to remove a macro definition.
Conditional compilation
1. #if constant expression //... #endif //Constant expressions are evaluated by the preprocessor. For example: #define __DEBUG__ 1 #if __DEBUG__ //.. #endif 2.Conditional compilation of multiple branches #if constant expression //... #elif constant expression //... #else //... #endif 3.Determine whether it is defined #if defined(symbol) #ifdef symbol #if !defined(symbol) #ifndef symbol 4.Nested instruction #if defined(OS_UNIX) #ifdef OPTION1 unix_version_option1(); #endif #ifdef OPTION2 unix_version_option2(); #endif #elif defined(OS_MSDOS) #ifdef OPTION2 msdos_version_option2(); #endif #endif
Application:
1. Compatible with development and release environment,
2. Compatible with multiple systems,
3. Prevent repeated inclusion of header files (#pragma once is used at the definition),
4. Realize multi line annotation, as follows:
5. Support nesting