C语言-动态内存开辟

本文详细阐述了C语言中内存的几个区域,包括栈区、堆区、全局区和常量区的用途和管理。强调了动态内存分配(如malloc、calloc、realloc)和释放(free)的重要性,以及如何避免内存泄漏。特别提到了柔性数组的使用和内存扩展的例子。
摘要由CSDN通过智能技术生成

开辟堆区空间

切记代码一定要记得释放

程序代码区

常量区存放常量。程序结束时由OS回收。

全局区(静态区)存放全局变量和静态变量。初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束时由OS回收。

堆区存放的变量(用new,malloc,calloc,realloc等分配内存函数得到的变量)由程序员分配释放。

栈区存放的变量(局部变量、函数参数等)由编译器自动分配释放。

int*p=(int*)melloc(sizeof(int))

用melloc开辟的空间

失败会返回一个NULL指针因此开辟完记得检查一下空间

成功会返回一个指针地址,这个指针是void*类型的,所以看需求给指针类型

不能开辟大小为0的地址

提供free函数用来动态释放内存空间

释放完指针变量还是存在的,记得p=NULL

如果释放了一个空指针则不做处理

不能使用free对同一块内存空间重复释放

free释放的是内存空间,而不是指针。

——释放,指针指向的内存空间可以被其他变量所占用,

但被占用前,内存空间中的内容仍然存在。但是无法判定是否被占用

如果非法使用动态内存非常危险,后果无法预料

动态内存是开辟在堆上的。栈里使用的内存计算机会自动回收开辟

calloc(10,sizeof(int))返回一个指针并初始化这篇空间并且把空间每个字节初始化为0

relloc内存拓展,调整动态开辟内存的大小

relloc(p,10*sizeof(int))拓展p指向的内存

1、如果开辟的空间大小小于p指向的空间后边的内存大小则直接开辟

2、如果小于就会开辟出一块新的空间,拷贝原来数据并且释放掉原来的空间

再次释放空间时只需要释放新开辟的空间就好了

内存泄漏

若动态开辟的内存一直没得到释放就可能会造成内存泄漏

这段代码传的str是值,是地址但是地址作为值传过去

void get(char*p) { p=(char*)(malloc(100)); } int main() { char str=NULL; get(str); }

内核空间

栈(向下增长)主要存运行时函数参数、局部变量、返回地址、返回数据 操作系统回收

内存映射段

堆(向上增长)程序若不释放可能有操作系统回收

数据段(全局数据、静态数据)操作系统回收

代码段(可执行代码?只读代码)例如char arr=“hello”;为常量字符串

柔性数组

include<string.h>
#include<errno.h>
struct st_type
{
    int i;//4字节
    int a[0];//柔性数组成员,也可以写int a[];
};
int main()
{
    //假设我现在需要a里有10个元素
    struct st_type*ps=(struct st_type*)malloc(sizeof(struct st_type) + 10 * sizeof(int));
    if (ps == NULL)//由于空间可能不够开辟导致malloc开辟失败,开辟失败会返回空指针
    {
        printf("%s\n", strerror(errno));
        return -1;//程序出问题后,跳出程序
    }
    //开辟成功
    int j = 0;
    for (j = 0;j < 10;j++)
    {
        ps->a[j] = j;
    }
    for (j = 0;j < 10;j++)
    {
        printf("%d ", ps->a[j]);//打印0-9
    }
    printf("\n");
    //如果想继续用柔性数组a进行打印
    //比如现在a里只有10个元素,我用完10个了,我还要继续来10个,用realloc追加
    struct st_type*ptr=realloc(ps, sizeof(struct st_type) + 20 * sizeof(int));//ps:realloc第二个参数是调整后的整体大小
    if (ptr == NULL)
    {
        printf("扩容失败\n");
        return -1;
    }
    else
    {
        ps = ptr;
    }
    //扩容成功
    int k = 0;
    for (k = 10;k < 20;k++)
    {
        ps->a[k] = k;
    }
    for (j = 0;j < 20;j++)
    {
        printf("%d ", ps->a[j]);//打印0-19
    }
    //释放空间
    free(ps);
    ps = NULL;
    return 0;
}
 NULL; return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值