C语言基础及指针⑤动态内存分配

【C语言进阶】动态内存管理/分配 首先我们再来回顾一下内存区域的划分: 一、为什么存在动态内存管理/分配? (1)因为内存太宝贵。 (2)如果全部是静止内存不能释放,对于小的程序可以运行完毕。但是对于大的程序,还没运行完,内存就要被占用完,此时就要发生内存泄露。 (3)假设给定一个占用内存可变大小的变量(假设是数组的长度len),那么给该变量通过函数动态分配内存后,分配内存的大小是根据数组的长度len决定的。假定用户输入len的大小是5,系统就会动态的给该数组分配长度为5的内存。 该段代码运行结束后,系统调用free(.. 阅读详情

接续上篇C语言基础及指针④函数指针

在上一篇我们了解C语言中的函数及函数指针 , 使用函数指针 , 模拟了网络请求的回调方式 , 今天我们来学习动态内存分配。

我们在使用java的时候 , 所有的内存都交由JVM做处理 , 我们无法直接控制 , 虽然很少导致内存溢出 , 但是程序占用内存却会越来越大 , 所以我们在使用Android手机的时候 , 刚开始很流畅 , 用着用着就非常卡 , 在打开大文件或是播放gif的时候 , 如果采用java编写处理引擎 , 则会比较卡 , 因为开辟的内存空间无法控制 , GC回收又不是即时的 , 这时候就需要我们使用JNI技术 , 使用C语言进行处理 。接下来 ,我们就来学习C语言中的动态内存分配 。

C语言中内存的大致分配:

内存描述特性
栈区是一个确定的常数(win 1~2M) 不同平台会有不同大小 超出会提示stackoverflow自动分配 , 自动释放
堆区用于动态内存分配手动分配和释放 , 可占用80%内存
全局区或静态区在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据(如字符串常量)只初始化一次
程序代码区代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次(每个进程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。代码区的指令中包括操作码和要操作的对象(或对象地址引用)

C语言中动态分配内存是在堆区 , java语言中new一个对象 , 也会在堆内存中开辟一块空间 , 来存储我们创建的这个对象 。在C语言中 , 我们在堆区开辟一块空间使用的关键字是malloc , malloc函数定义:

void* __cdecl malloc(
    _In_ _CRT_GUARDOVERFLOW size_t _Size
    );

使用如下:

// 动态内存分配 , 使用malloc函数在对内存中开辟连续的内存空间 , 单位是:字节
// 申请一块40M的堆内存
int* p = (int*)malloc(1024 *1024 * 10 * sizeof(int));

下面我们来模拟一下病毒:

/*动态内存分配*/
void heapFunc() {
    // 动态内存分配 , 使用malloc函数在对内存中开辟连续的内存空间 , 单位是:字节
    // 申请一块40M的堆内存
    int* p = (int*)malloc(1024 *1024 * 10 * sizeof(int));
}


void main() {

    while (1)
    {
        // 睡一秒执行一次
        Sleep(1000);
        heapFunc();
    }

    getchar();

}

打开任务管理器 , 我们可以看到我们共存所占内存 , 正在以40M每秒的速度 , 蹭蹭的往上涨 , 以前的蠕虫病毒就是如此 , 不断的消耗内存 , 然后导致系统崩溃 。

在使用静态内存分配的时候 , 内存大小是固定的 , 很容易超出栈内存的最大值, 预估大小往往大大的超出使用大小 , 浪费内存 。使用malloc申请内存 , 最重要的一个点就是可以动态改变申请的内存大小 , 可以使用realloc函数来重新申请内存大小,realloc函数定义:

void* __cdecl realloc(
    _Pre_maybenull_ _Post_invalid_ void*  _Block,
    _In_ _CRT_GUARDOVERFLOW        size_t _Size
    );

使用如下:

// 重新申请内存大小 , 传入申请的内存指针 , 申请内存总大小
int* p2 = realloc(p, (len + add) * sizeof(int));

下面我们来应用一下:

void main() {

    int len;
    printf("请输入首次分配内存大小:");
    scanf("%d", &len);
    // 动态分配内存 , 内存空间是连续的
    int* p = (int*)malloc(len * sizeof(int));
    // 给申请的内存空间赋值
    int i = 0;
    for (; i < len ; i++)
    {    // 生成随机数赋值
        p[i] = rand() % 100;

        printf("array[%d] = %d , %#x\n", i, p[i], &p[i]);
    }

    // 在原有内存上面,重新分配内存大小
    printf("请输入增加的内存大小");
    int add;
    scanf("%d", &add);
    // 重新申请内存大小 , 传入申请的内存指针 , 申请内存总大小
    int* p2 = (int*)realloc(p, (len + add) * sizeof(int));
    // 给新申请的内存空间赋值
    int j = len;
    for (; j < len + add ; j++)
    {
        p2[j] = rand() % 200;
    
    }

    // 打印
    j = 0;
    for (; j < len + add; j++)
    {
        printf("array[%d] = %d , %#x\n", j, p2[j], &p2[j]);
    }
    
    // 回收申请的动态内存
    if (p2 != NULL)
    {
        free(p2);
        p2 = NULL;
    }
        
    system("pause");
}

使用malloc和realloc配合 , 就可以模拟出我们java中的集合类型,动态改变内存空间大小 。 使用malloc 第一次申请的内存首地址和第二次申请的内存首地址可能相同也可能不同 , 因为申请的内存是连续的 , 所有 , 但第一次申请的空间的后续空间不够用时 , 会重新开辟新的空间 , 并将数据copy到新的空间里面 。

内存分配的几个注意细节:
1.不能多次释放
2.释放完之后 , 给指针置NULL,标志释放完成
3.内存泄漏 (p重新赋值之后 , 再free , 并没有真正释放 , 要在赋值之前释放前一个内存空间)



作者:逝我
链接:https://www.jianshu.com/p/93db7c692d1b
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

MATLAB实战:四桥臂逆变器3D-SVPWM调制算法仿真全流程(附代码) 本文提供了一份完整的MATLAB/Simulink实战指南,详细解析了四桥臂逆变器的3D-SVPWM调制算法仿真全流程。文章从工程实践出发,手把手指导如何搭建模型,涵盖从abc静止坐标系变换、三维空间矢量区域判定、作用时间计算到PWM信号生成与调试等核心环节,并附有代码示例和常见问题解决方案,旨在帮助工程师快速掌握这一应对不平衡负载的高效调制技术。 阅读详情

相关推荐

Tesla V100 Windows 部署实战:从驱动安装到模式切换的避坑指南

本文是一份详细的Tesla V100在Windows系统下的部署实战指南。文章从硬件组装、系统选择讲起,重点阐述了驱动安装的正确方法,并深入剖析了将计算卡从TCC模式切换至WDDM模式的诱惑与潜在陷阱。最终,作者推荐保持默认TCC模式,并提供了使用nvidia-smi命令行等稳定可靠的显卡监控方案,旨在帮助用户避开常见坑点,高效利用这张专业计算卡进行AI计算等任务。

java5的博客 1706

C语言:动态内存分配

当我们在创建一个变量时,这个变量的字节大小(存储空间)是固定的:比如,我们创建一个整型变量a, 它的字节大小就是4个字节。int a = 0;而当我们想要自主管理我们的内存,当我们需要多大的空间我们就可以开辟多大的空间,这样就具有了灵活性。如果想要实习这样的功能,就需要学习今天我要分享的博客:动态内存分配。

2201_75479723的博客 1298

通信原理 | python调制识别数据及代码

数据集包含了从-20dB 到+18dB 总共 20 个信噪比(步长为 2)下的 11 种调制信号, 包括 AM-DSB、 AM-SSB 和 WBFM 三种模拟调制信号,以及 BPSK、 QPSK、 8PSK、 CPFSK、 GFSK、 PAM4、 QAM16 和 QAM64 八种数字调制信号。其中信号的中心频率为 200KHz,采样频率为 1Msamp/s,且每个信噪比下每种调制信号包含 1000 个信号。其中每个信号包含 IQ 两路数据,且每一路数据都包含有 128 个采样点。

若北辰 1758

C语言中指针动态内存的申请和释放

什么是动态内存的申请和释放? 当程序运行到需要一个动态变量时,需要向系统的堆中申请一块内存,用来存储这块变量,这就是内存的申请。当程序不需要这个变量时,就需要把申请的这块内存释放掉,这就是内存的释放。往往内存的申请和释放是一起使用的,只要有内存的申请,就要有内存的释放,避免出现内存泄漏。 C语言指针的申请: (1).在C语言中使用malloc函数申请内存,函数原形:void* malloc(size_t size); 参数size代表申请的内存的字节数,参数size_t代表指针的...

u011555996的博客 2万+

逻辑电平(TTL/CMOS/LVDS/LVPECL/CML)

逻辑电平介绍 TTL------晶体管-晶体管逻辑门(Transistor-Transistor Logic gate) TTL采用5V电源

sinat_15677011的博客 2万+

25 - GRACE Mascon数据缺失月份数据插值

本篇基于文章的相关内容和文章公开的奇异谱分析(SSA)插值算法程序包,对grace Mascon数据种缺失的月份进行 插值 ,总结了使用程序包的相关过程,可以将该程序应用到其他数据处理插值计算中。

weixin_43339605的博客 1842

Android NDK开发(一)C语言基础语法

最近一段时间在攻克Android NDK开发。虽然大学的时候主要的学习是放在C/C++上的,但是自从大学毕业之后,就把所有学到的只是都还给老师了,所以,趁着这个机会,将C语言和NDK开发好好的总结一下,学习一下。 自己在网上也看了很多博客,感觉大神们写的都是比较难以理解,特别是像现在这种工作了一天的状态,想要再看这些东西的时候,都感觉花眼了。所以,自己希望能够将基础知识理顺。 首先先来...

牛谱乐的博客 6989

SAP CAP 编程模型简介

官网 CAP 是用于构建企业级服务和应用程序的语言、库和工具框架。它引导开发人员沿着经过验证的最佳实践和大量现成的解决方案来应对重复性任务的“黄金之路”。 基于 CAP 的项目受益于对领域的主要关注。我们没有深入研究过于技术性的学科,而是专注于在快速变化的云技术世界中加速开发和保护投资。 CAP 框架融合了经过验证和广泛采用的开源和 SAP 技术,如下图所示。 在开源技术之上,CAP主要增加了: 核心数据服务 (CDS) 作为我们用于域模型和服务定义的通用建模语言。 用于 Node.js 和 Ja

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1545

动态存储管理_free崩溃

一、 生存期 从变量值的存在时间(生存期)来观察。有的变量在程序运行的整个过程都是存在的,而有的变量则是在调用其所在函数才临时分配存储单元,而在函数调用结束后该存储单元就马上释放了,变量就不存在了。 1.1 静态存储方式 是指在程序运行期间由系统分配固定的存储空间的方式。 1.2 动态存储方式 是指在程序运行期间根据需要进行动态的分配存储空间的方式。下面我们讨论一下free因何崩溃。 ...

仰望星空 993

Python爬虫实战:高效爬取中国版权登记数据

本文将详细介绍如何使用Python最新技术栈构建一个高效、稳定的中国版权登记数据爬虫系统。我们将使用Playwright+Asyncio实现无头浏览器自动化,结合Redis分布式任务队列和MongoDB数据存储,打造一个能够应对反爬机制的企业级数据采集方案。文章包含完整代码实现、性能优化技巧以及法律合规建议,帮助开发者快速掌握大规模数据采集的核心技术。本文详细介绍了2024年使用Python最新技术栈构建中国版权登记数据爬虫的完整方案。基于Playwright的无头浏览器自动化。

2201_76125261的博客 1898

【Python基础】01 如何安装Python及集成环境

本文详细介绍了Python 3.13开发环境的完整搭建流程,涵盖三大操作系统(Windows/macOS/Linux)的Python安装方法、PyCharm专业IDE的配置使用,以及pip包管理工具的应用技巧。内容包括:Python 3.13各系统安装指南、PyCharm社区版与专业版的安装配置、环境验证方法、pip的基本命令与镜像源优化、虚拟环境管理,以及常见问题的解决方案。通过本教程,读者可获得一个高效完备的Python开发环境,为后续编程学习打下坚实基础。

nmdbbzcl的博客 1417

【C语言进阶篇】动态内存分配和数组的动态内存分配

本文主要介绍了C语言中常用的内存函数和数组的动态内存分配,并稍微提了一嘴柔性数组。动态内存分配是C语言中十分重要的一环,其中对二维数组的动态内存分配是个难点,需要多思考。

Ye_Ming_OUC的博客 3万+

康复训练监测系统:基于YOLOv8的患者动作规范识别

本文系统介绍了基于YOLOv8的康复训练动作规范识别系统,从理论背景、数据准备、模型训练、推理应用到UI界面,提供了完整技术链条及代码示范。希望对康复领域的智能监测应用提供参考和借鉴。

YOLO 453

C语言动态内存分配详解

文章目录前言一、为什么存在动态内存分配1、已掌握的内存开辟方式2、上述开辟空间方式的特点3、为什么存在动态内存分配二、动态内存函数的介绍1、malloc2、free3、calloc4、realloc三、常见的动态内存错误四、几个经典的笔试题五、柔性数组总结 前言 自从前两次博客写完以后,感觉对于我本人来说,收获很大,尤其是将学过的知识再度温习一遍,感觉基础扎实了很多,所以就养成了一个习惯,每学完一个模块,都会写一篇博客,不仅仅是写个我自己的,也是想通过这篇博客,与大家分享一些我的见解。本来周四就学完了动态内

WZRbeliever的博客 8415

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C语言 - 动态内存分配

malloc calloc relloc free 动态申请内存

good good study, day day up! 6052

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C语言指针常量、常量指针动态内存分配

每个C语言进程都拥有一片结构相同的虚拟内存,所谓的虚拟内存,就是从实际物理内存映射出来 的地址规范范围,最重要的特征是所有的虚拟内存布局都是相同的,极大地方便内核管理不同的进 程。虚拟内存中,内核区段对于应用程序而言是禁闭的,它们用于存放操作系统的关键性代码,另外由 于 Linux 系统的历史性原因,在虚拟内存的最底端 0x0 ~ 0x08048000 之间也有一段禁闭的区段, 该区段也是不可访问的。这些不同的内容,所存储的区域是不同的,且不同的区域有不同的特性。

weixin_64487558的博客 2039

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C语言:指针4(常量指针和指针常量及动态内存分配)

常量:分为字面量和只读常量,字面量就是我们平时直接操作的量:只读常量使用关键字 const 修饰,凡是被这个关键字修饰 的变量,一旦赋值,值就不能改变。

一起学习 2481

C语言-动态内存分配讲解

我们在处理内存时,内存区域主要分为三块区域,分别为:栈区,堆区,静态区而我们经常使用的语句其实都是在栈区开辟空间的,如:int a;float b;char c;但是使用这样的声明,在栈区开辟空间时是有一定风险的存在风险:1.开辟出来的空间是固定的,不能进行具体字节大小的修改,所以可能浪费掉栈区的空间大小2.栈区空间开辟太大可能导致栈溢出因此,我们可以将一些东西存储在堆区中,堆区的空间是本身就存在的,我们要做的就是分配出来并利用这些空间,因此也叫做动态内存分配。

2301_80349538的博客 3940

C语言 动态内存分配

C语言 动态内存分配一、动态内存分配函数1.1 malloc和free函数 前言:之前学习了数组,数组的元素储存在内存中连续位置。在声明数组时必须要指定数组的元素个数,即数组空间大小在声明时已经确定了。但是需存放的元素个数常常在运行时才能知道(取决于输入的数据)。这会有几个缺点:1. 当输入元素个数大于数组声明的元素个数时会带来意想不到错误 2. 当输入元素个数小于数组声明的元素个数时会带来内存空间的浪费 3. 数组大小不能动态调整。 C语言提供了相关的动态内存分配函数,需要多大内存空间就分配多大内存空间,

kjl167的博客 7301

C语言指针操作(十)动态内存分配与指向它的指针变量

全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个称为栈 ( stack ) 的区域。除此以外,C语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据不必在程序的声明部分定义,也不必等到函数结束时才释放,而是需要时随时开辟,不需要时随时释放。这些数据是临时存放在一个特别的自由存储区,称为堆 ( heap ) 区。可以根据需要,向系统申请所需大小的空间。

伯努利 3645

《C和指针》 第11章 动态内存分配

动态内存分配是C语言编程中一项重要的技术,它允许程序在运行时根据实际需求灵活分配和管理内存。malloccalloc和realloc函数提供了不同方式的内存分配和调整功能,free函数用于释放不再使用的内存。在使用动态内存分配时,要注意避免常见的错误,如内存泄漏、悬空指针、多次释放和内存越界等。正确使用动态内存分配可以提高程序的效率和灵活性,使程序能够处理各种动态变化的情况。

qq_40844444的博客 1276

【C语言】动态内存分配

本篇文章会详细给大家介绍C语言中关于动态内存分配的知识,超级详细,相信你看完会有新的收获,那就来狠狠回顾100万遍把~

Become Mad的博客 2538

C语言指针 动态内存分配

C语言指针(连载ing) 引言:本文章根据比特科技张鹏伟老师的C语言课程的指针进阶内容所做笔记 指针进阶(一) 1.一个数组的数组名就是它的首元素地址 int arr[5] = {0}; //声明一个有5个整型元素的数组 printf("%p\n", arr); //打印这个数组首元素的地址 输出一个16进制数代表地址 printf("%p\n", &arr[0]); //用一种更加直接的方式去打印首元素的地址,别忘了取地址符 可以发现两个地址是相同

m0_51513374的博客 2650

「C/C++」C/C++ 之 动态内存分配

在C和C++编程中,内存管理是一个核心且复杂的主题。与静态内存分配(在编译时确定大小)不同,动态内存分配允许程序在运行时根据需要分配和释放内存。本文将深入探讨C和C++中的动态内存管理,包括内存分配、释放、常见错误以及最佳实践。动态内存管理是C和C++编程中的一个重要且复杂的主题。通过合理使用内存分配和释放函数,以及遵循最佳实践,程序员可以编写出高效且健壮的代码。然而,也需要时刻警惕内存泄漏、野指针等潜在问题,以确保程序的稳定性和安全性。的需要,从而降低了内存泄漏的风险。

何曾参静谧的博客 1561

C语言中的动态内存分配

大家好,今天简单讲一讲C语言中的动态内存分配。 截至目前,我们所使用的变量似乎都是在栈区(如局部变量、函数形参)和静态区(如全局变量、static修饰的变量),但是我们很早就知道除了栈区、静态区,在内存中还有‘堆’这样的一个区域。其实,这块内存就是用来动态内存分配的。 其实想一下就知道光靠栈区和静态区在处理问题时是很不灵活的(因为其开辟的空间是固定的),比如在声明数组时必须指定数组的大小(当然在C99中存在变长数组),但有时候我们也不能明确的指出要用多少空间,我们希望这块空间可大可小,既不过大,造成空间

m0_62797154的博客 6152
上一篇: C语言基础及指针④函数指针
下一篇: Android开发之爱奇艺Flutter跨平台Hybrid实践
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值