Pointer (three) dynamic memory

12_pointer (three) dynamic memory

A memory area partition

1 code area

Save code

2 Constant area

Store constants: numeric constants, character constants, string constants, symbolic constants (define), address constants...

3 Global area (static global area)

Key words:

  1. Static variable (static) static: static
  2. Global variable
#include<stdio.h>

int b = 0;                 //普通全局变量
static int d = 0;          //静态全局变量

int main() {
    
    

	int a = 0;             //普通局部变量(主函数范围内)
	static int  c = 0;     //静态局部变量

	return 0;
}

Role and difference:

  1. Scope: the area of ​​action
  2. Life cycle (life cycle): the period of time that works
#include<stdio.h>

//全局变量生存周期:程序开始到程序结束
int b = 0;                 //普通全局变量
	//普通全局变量作用域(项目作用域):作用域为整个项目,不同文件时用extern声明 
	//extern: extern + 完整定义
    //
static int d = 0;          //静态全局变量
	//静态全局变量作用域(文件作用域):作用域为当前文件

int main() {
    
    
	//作用域: 当前语块(变量定义到大括号结束)
	int a = 0;             //普通局部变量
	//生存周期:当前语块
	static int  c = 0;     //静态局部变量
	//生存周期:程序开始到程序结束

	return 0;
}

void  fun() {
    
    
	a = 10;               //报错:未定义标识符
	b = 10;
	c = 10;               //报错:未定义标识符
	d = 10;
	//a和c都为局部变量(作用域在变量定义到当前函数结束)
}

to sum up:

  1. Contains global or static variables: the life cycle is from the beginning of the program to the end of the program, otherwise the life cycle is the current block (stored in the static global area)
  2. Static global area: from the beginning of the program, the system automatically allocates memory, to the end of the program, the system automatically reclaims memory
4 Stack area

Store ordinary local variables, the system automatically allocates memory from the beginning of the definition, and the system automatically reclaims temporary memory when the function is out

5 heap area

Manual application by the programmer, manual release

Two void* pointers

Null pointer

#include<stdio.h>

int main() {
    
    
	void* p = NULL;
	p + 1; //错误:表达式必须是指向完整对象类型的指针
	p++;   //错误:表达式必须是指向完整对象类型的指针

	int* pn = NULL;
	pn = p;//错误:不能将"void*"类型的值分配到"int*"类型的实体
	p = pn;//正常执行

	short* psh = NULL;
	p = psh;

	*p;    //错误
	return 0;
}

1 Can not be offset

2 Can not increase or decrease

3 can accept any other type of pointer

4 Can not directly give other types of pointer values ​​(can be forced)

5 Cannot fetch content directly

The pointer of void* type does not know its length (incomplete)

Three dynamic application of memory

  1. How to apply for release

    head File:

    #include<stdlib.h>
    

    Application

    void* malloc(size_t _Size);               // 参数:要在堆区申请的字节数
    void* calloc(size_t _Count, size_t _Size);// 参数:类型长度, 个数
    

    freed

    void free(void* _Memory);                 // 参数:地址(释放内存的首地址)
    

    The memory must be released after the application. The pointer must be emptied after the release.

  2. Memory leaks and wild pointers

    Memory leak: The requested memory is not released

    Wild pointer: the pointer points to a place that shouldn't be pointed

  3. Simple application example

    1.1 Use malloc to apply for an int type of memory (4 bytes)

    	//1. 申请
    	int* p = (int*)malloc(sizeof(int));//void* 给值要进行强转
    	//2. 使用
    	*p = 100;
    	//3. 释放
    	free(p);
    	//4. 置空
    	p = NULL;
    

    1.2 Use malloc to apply for ten int type memory (40 bytes)

    	//1. 申请
    	int* p1 = (int*)malloc(sizeof(int) * 10);
    	//2. 使用
    	if (p1) {
          
           //未申请成功,函数返回NULL 由此判断是否申请成功
    		//指针偏移使用
    		p1[0] = 1;
    		p1[2] = 10;
    	}
    	else printf("申请失败");
    	//3. 释放
    	free(p1);
    	//4. 置空
    	p1 = NULL;
    

    2.1 Use calloc to apply for an int type of memory (4 bytes)

    	//1. 申请
    	int* p2 = (int*)calloc(sizeof(int), 1);
    	//2. 使用
    	*p2 = 100;
    	//3. 释放
    	free(p2);
    	//4. 置空
    	p2 = NULL;
    
    Complete code
    #include<stdio.h>
    #include<stdlib.h>
    int main() {
          
          
    	//1.1 使用malloc申请一个int类型大小的内存(4字节)
    	//1. 申请
    	int* p = (int*)malloc(sizeof(int));//void* 给值要进行强转
    	//2. 使用
    	*p = 100;
    	//3. 释放
    	free(p);
    	//4. 置空
    	p = NULL;
    
    	//1.2 使用malloc申请十个int类型大小的内存(40字节)
    	//1. 申请
    	int* p1 = (int*)malloc(sizeof(int) * 10);
    	//2. 使用
    	if (p1) {
          
           //未申请成功,函数返回NULL 由此判断是否申请成功
    		//指针偏移使用
    		p1[0] = 1;
    		p1[2] = 10;
    	}
    	else printf("申请失败");
    	//3. 释放
    	free(p1);
    	//4. 置空
    	p1 = NULL;
    
    	// 使用calloc申请一个int类型大小的内存(4字节)
    	//1. 申请
    	int* p2 = (int*)calloc(sizeof(int), 1);
    	//2. 使用
    	*p2 = 100;
    	//3. 释放
    	free(p2);
    	//4. 置空
    	p2 = NULL;
    	return 0;
    }
    
  4. Dynamic array

    Dynamic array (not an array, but the memory requested by the heap area)

    Class one-dimensional array
    #include<stdio.h>
    #include<stdlib.h>
    int main() {
          
          
    
    	//1. 申请
    	int len = 10;
    	int* arr = (int*)malloc(sizeof(int) * len);
    	//2. 使用
    	if (arr) {
          
           //未申请成功,函数返回NULL 由此判断是否申请成功
    		//指针偏移使用
    		for (size_t i = 0; i < len; i++) {
          
          
    			arr[i] = i;
    		}
    		for (size_t i = 0; i < len; i++) {
          
          
    			printf("%2d",arr[i]);
    		}
    		printf("\n");
    	}
    	else printf("申请失败");
    	//3. 释放
    	free(arr);
    	//4. 置空
    	arr = NULL;
    	return 0;
    }
    
    Two-dimensional array-like
    #include<stdio.h>
    #include<stdlib.h>
    int main() {
          
          
    	// 申请类似于int arr[3][4];
    	//1.  申请
    	//1.1 申请3个指针
    	int** pp = (int**)calloc(sizeof(int*), 3); //函数参数用一级指针,函数应返回二级指针
    	//1.2 分3次申请4个int大小的内存
    	for (size_t i = 0; i < 3; i++) {
          
          
    		pp[i] = (int*)calloc(sizeof(int), 4);
    	}
    	// ==> 不一定像真正的二维数组一样内存连续
    
    	//2. 使用
    	for (size_t i = 0; i < 3; i++) {
          
          
    		for (size_t j = 0; j < 4; j++) {
          
          
    			pp[i][j] = i * 10 + j;
    			printf("%3d", pp[i][j]);
    		}
    		printf("\n");
    	}
    	printf("\n");
    	//3. 释放
    	free(pp);
    	//4. 置空
    	for (int i = 0; i < 3; i++) {
          
          
    		pp[i] = NULL;
    	}
    	return 0;
    }
    
    Simple array expansion

    Ideas:

    1. Given default length

    2. adding data

    3. If it is full, automatically expand

    #include<stdio.h>
    #include<stdlib.h>
    int main() {
          
          
    	// 1. 给定默认长度
    	// 2. 添加数据
    	// 3. 如果装满了,自动扩容
    
    	// 默认初始长度:10
    	int len = 10;
    
    	// 申请长度为len(10)个int大小的内存
    	int* p = (int*)calloc(sizeof(int), len);
    	int* ptemp = p;       // 保存p当前地址
    
    	int i = 0;            // 下标
    	int num = 0;          // 用来接收每一次的输入
    
    	// 添加数据(重复输入)_结束标志: -1
    	while (scanf_s("%d", &num), num != -1) {
          
          
    		// 1 长度足够
    		if (i < len) {
          
          
    			ptemp[i++] = num;
    		}
    		// 2 长度不够,需要扩容
    		else {
          
          
    			// 自定义扩容规则: 变为原来2倍
    			len *= 2;
    			p = (int*)calloc(sizeof(int), len);     //重新申请一段内存
    			// 拷贝之前内存中的数据
    			for (size_t j = 0; j < i; j++) {
          
          
    				p[j] = ptemp[j];
    			}
    			p[i++] = num;      //添加当前需要添加的数据
    			free(ptemp);
    			ptemp = p;         //ptemp 重新指向新内存
    		}
    	}
    	// 检验
    	for (size_t j = 0; j < i; j++) {
          
          
    		printf("%3d",ptemp[j]);
    	}
    	printf("\n当前内存长度:%d\n当前数据个数:%d\n",len,i);
    
    	free(p);      //释放
    	// p和ptemp为同一段内存,切勿重复释放
    	p = ptemp = NULL;
    
    	return 0;
    }
    

Guess you like

Origin blog.csdn.net/zhuiyizhifengfu/article/details/113863723