动态内存分配

来源:互联网 发布:淘宝云客服兼职 编辑:程序博客网 时间:2024/05/01 16:48

一:传统数组(静态数组)的缺点

1:数组的长度必须事先指定,并且是常整数,不能是变量 int a[5];
2:传统数组程序员无法由程序员释放,只能由系统释放。(并且只能在数组所在函数结束才能释放)
3:数组的长度在函数运行期间不能动态的扩充和缩小
4:A函数定义的传统数组,在A函数结束时,在B函数中是不能使用的,因为已经释放。也就是传统数组不能跨函数。

区分:静态存储与内存的静态开辟

二:为什么要动态分配内存

用来解决传统数组的四个缺陷

三:动态内存分配举例,以及动态数组的构造

方式:malloc函数,在堆开辟空间

int  i =5;  //静态分配int *p  = (int *) malloc(4); //动态分配   NULL  (void *)0

1:malloc是由程序员在堆栈动态开辟空间
2:返回值开辟空间的首地址,但是类型是void *,需要强制类型转换
3:分配的内存空间应该能整除类型所占的字节数
4:包含头文件malloc.h
5:只能用free(p)来释放p所指向的动态开辟的内存空间。
6:对动态内存空间的操作,用*p来操作。
7:可以用多个指针指向这个动态空间
8:当有多个指针只向这个动态空间时,只能用free一个指针,多次重复释放要被报错
9:可以将动态开辟的的内存指针作为函数参数

问题:p的分配类型是动态的还是静态的?当调用free(p)后,p的内存空间会被释放么?
例子:动态构建一个一维数组:

#include <stdio.h>#include <malloc.h>/*  动态构造数组*/int main(int argc, char *argv[]){    int len,i;    scanf("%d",&len);    int *p = (int *)malloc(4*len); //构造了一个一维数组,长度是4*len个字节    for(i=0;i < len;i++)      p[i] = i;    for(i=0;i < len;i++)      printf("%4d",p[i]);      free(p);    return 0;}

动态扩充数组的长度,也就是在程序运行时动态扩充:realloc(首地址,总共字节数)
作用:将原来动态开辟的动态内存重新开辟一个字节数,如果这个数比以前的大,前面的数据保存。如果比原来的小,保留前面的数据。

#include <stdio.h>#include <malloc.h>/*  动态构造数组,并实现扩充与缩小*/int main(int argc, char *argv[]){    int len,i;    scanf("%d",&len);    int *p = (int *)malloc(20); //构造了一个一维数组,长度是4*len个字节    if(len > 5){      p = (int *)realloc(p,len*4);    }    for(i=0;i < len;i++)      p[i] = i;    for(i=0;i < len;i++)      printf("%4d",p[i]);      free(p);    return 0;}

注意:扩充或者缩放的内存单元是新开辟的内存单元。这个过程中有值的拷贝过程。返回值是新开辟的地址空间首地址。

四:静态内存和动态内存的比较

静态开辟的内存:在栈中开辟,由编译器分配,由系统自动释放
动态开辟的内存:在堆中开辟,由程序员开辟,由程序员自动释放。

五:跨函数使用内存的问题

#include <stdio.h>#include <malloc.h>int main(int argc, char *argv[]){    void fun(int **);    int *p;    fun(&p); //要想在子函数修改p本省的值,只能发送p的地址   printf("%d  ",*p);    return 0;}void fun(int **q){  *q = (int *)malloc(sizeof(int));  **q = 5;}
原创粉丝点击