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;
}

 

posted @ 2024-05-07 18:39  万溪汇海  阅读(151)  评论(0编辑  收藏  举报