C语言之动态内存分配
动态内存分配
传统数组的缺点
1.数组长度必须事先制定,且只能是常整数,不能是变量
例子:
int a[5]; //ok
int len=5; int a[len];//error
2.传统形式定义的数组,该数组的内存程序员无法手动释放
3.在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放
4.数组的长度一旦定义,其长度就不能再更改,数组的长度不能再函数运行的过程中动态的扩充或缩小
5.A函数定义的数组,在A函数运行期间可以被其他函数使用,但A函数运行完毕之后,A函数中的数组将无法被其他函数使用
传统方式定义的数组不能跨函数使用
为什么需要动态分配内存
动态数组很好的解决了传统数组的这5个缺陷
传统数组也叫静态数组
动态内存分配举例 动态数组的构造
1 # include <stdio.h> 2 # include <malloc.h> //不能省 3 4 //malloc是memory(内存)allocate(分配)的缩写 5 6 int main(void) 7 { 8 int i = 5; //分配了4个字节 静态分配 9 int* p = (int *)malloc(4); //9行 10 /* 11 1.要使用malloc函数,必须添加malloc.h这个头文件 12 2.malloc函数只有一个形参,并且形参是整型 13 3.4表示请求系统为本程序分配4个字节 14 4.malloc函数只能返回第一个字节的地址 15 5.9行分配了12个字节,p变量占8个字节,p所指向的内存占4个字节 16 6.p本身所占的内存是静态分配的,p所指向的内存是动态分配的 17 */ 18 19 *p = 5; //*p代表的就是一个int变量,只不过*p这个整型变量的内存分配方式和i变量的分配方式不同 20 free(p); //free(p)表示把p所指向的内存给释放掉,p本身的内存是静态的,不能由程序员手动释放 21 //p本身的内存只能在p变量所在的函数运行终止时,由系统自动释放 22 printf("你好呀!\n"); 23 24 return 0; 25 }
1 # include <stdio.h> 2 # include <malloc.h> 3 4 void f(int * q) 5 { 6 *q = 200; 7 //free(q); //把q所指向的内存释放掉 本语句必须注释掉,否则会导致第17行的代码出错 8 } 9 10 int main(void) 11 { 12 int* p = (int*)malloc(sizeof(int)); //sizeof(int)返回值是int所占的字节数 13 *p = 10; 14 15 printf("%d\n", *p); //10 16 f(p); //p是int * 类型 17 printf("%d\n", *p); //200 18 }
1 # define _CRT_SECURE_NO_WARNINGS 1 2 # include <stdio.h> 3 # include<malloc.h> 4 5 int main(void) 6 { 7 int a[5]; //如果int占4个字节的话,则本数组总共包含有20个字节,每4个字节被当做了一个int变量来使用 8 int len; 9 int* pArr; 10 int i; 11 12 //动态的构造一维数组 13 printf("请输入您要存放的元素的个数:"); 14 scanf("%d", &len); 15 pArr = (int*)malloc(4 * len);//本行动态的构造了一个一维数组,该一维数组的长度是len, 16 //该数组的数组名pArr,该数组的每个元素的类型是int,类似于 int pArr[len]; 17 //对一维数组进行操作,如:对动态一维数组进行赋值 18 for (i = 0;i < len;i++) 19 scanf("%d", &pArr[i]); 20 21 //对一维数组进行输出 22 printf("一维数组的内容是:"); 23 for (i = 0;i < len;i++) 24 printf("%d\n", pArr[i]); 25 26 return 0; 27 }
多级指针
# include <stdio.h> int main(void) { int i = 10; int* p = &i; int** q = &p; int*** r = &q; //r=&p; //error 因为r是int *** 类型 r只能存放 int ** 类型变量的地址 printf("i=%d\n", ***r); return 0; }
#include <stdio.h> void f(int **p) { //*q就是p } void g() { int i = 10; int* p = &i; f(&p); //p是int *类型 ,&p是int **类型 } int main(void) { g(); return 0; }
静态内存和动态内存的比较
跨函数使用内存的问题
# include <stdio.h> void f(int ** q) //q是个指针变量,无论q是什么类型的指针变量,都只占4个字节 { int i = 5; //*q等价于p //*q = i; //error 因为*q=i;等价于p=i;这样写是错误的 *q = &i; } int main(void) { int* p; f(&p); printf("%d\n", *p);//本语句语法没有问题,但逻辑上有问题,函数执行完毕后,分配的内存自动释放,该语句操作了本应该释放掉的内存 return 0; }
正确写法
# include <stdio.h> # include <malloc.h> void f(int** q) { *q =(int *)malloc(sizeof(int)); **q = 5; } int main(void) { int* p; f(&p); printf("%d\n", *p); return 0; }