C语言实例_实现malloc与free函数完成内存管理

news2025/1/17 21:47:56

一、malloc和free函数介绍

在C语言中,mallocfree是用于动态内存管理的函数。

image-20230627232221413

(1)malloc函数

malloc函数用于在堆(heap)中分配指定大小的内存空间,并返回一个指向该内存块的指针。

原型如下:

void* malloc(size_t size);
  • size参数表示要分配的内存块的大小,以字节为单位。
  • 函数返回一个指向分配内存块的指针,如果分配失败,则返回NULL

使用场景:

  • 动态分配内存,例如在程序运行时根据需要创建数据结构。
  • 为字符串、数组、结构体等动态分配内存空间。

使用方法:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr;
    int num = 5;

    // 动态分配内存
    ptr = (int*)malloc(num * sizeof(int));
    if (ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 使用指针访问和操作分配的内存
    for (int i = 0; i < num; i++) {
        ptr[i] = i + 1;
    }

    // 打印分配的内存
    for (int i = 0; i < num; i++) {
        printf("%d ", ptr[i]);
    }

    // 释放内存
    free(ptr);

    return 0;
}

(2)free函数

free函数用于释放之前通过malloccalloc函数动态分配的内存空间。

原型如下:

void free(void* ptr);
  • ptr参数是一个指向先前分配的内存块的指针。如果ptrNULL,则free函数不执行任何操作。

使用场景:

  • 释放通过malloccallocrealloc等函数动态分配的内存。
  • 避免内存泄漏,即释放不再使用的内存,以便其他代码可以使用该内存。

使用方法:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(5 * sizeof(int));
    if (ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 使用动态分配的内存

    // 释放内存
    free(ptr);

    return 0;
}

一旦调用了free函数,就应该避免继续使用已释放的内存,已释放的内存将不再属于程序的有效内存区域,并且可能被其他部分重用。在释放内存后继续使用已释放的内存会导致未定义的行为和潜在的错误。

二、实现自己的malloc和free函数

定义一个数组 unsigned char buff[1024*100]; 然后使用C语言代码写个my_malloc和my_free函数,对这个buff数组的空间进行管理。 用户调用my_malloc和my_free函数管理这段空间。

实现代码:

#include <stdio.h>
#include <stdlib.h>

#define BUFF_SIZE (1024 * 100)

unsigned char buff[BUFF_SIZE];

typedef struct {
    unsigned char* start;
    size_t size;
} MemoryBlock;

MemoryBlock memoryBlocks[BUFF_SIZE] = {0};
int numBlocks = 0;

void* my_malloc(size_t size) {
    // 寻找空闲块
    for (int i = 0; i < numBlocks; i++) {
        if (memoryBlocks[i].size == 0 && size <= BUFF_SIZE) {
            memoryBlocks[i].start = buff;
            memoryBlocks[i].size = size;
            return memoryBlocks[i].start;
        }
    }

    // 分配新的块
    if (numBlocks < BUFF_SIZE) {
        memoryBlocks[numBlocks].start = buff + numBlocks;
        memoryBlocks[numBlocks].size = size;
        numBlocks++;
        return memoryBlocks[numBlocks - 1].start;
    }

    // 分配失败
    return NULL;
}

void my_free(void* ptr) {
    // 查找要释放的块
    for (int i = 0; i < numBlocks; i++) {
        if (memoryBlocks[i].start == ptr) {
            memoryBlocks[i].size = 0;
            break;
        }
    }
}

int main() {
    // 使用my_malloc和my_free进行内存管理
    unsigned char* ptr1 = (unsigned char*)my_malloc(10);
    unsigned char* ptr2 = (unsigned char*)my_malloc(20);

    if (ptr1 != NULL && ptr2 != NULL) {
        // 使用分配的内存
        for (int i = 0; i < 10; i++) {
            ptr1[i] = i;
        }

        for (int i = 0; i < 20; i++) {
            ptr2[i] = i + 10;
        }

        // 打印分配的内存
        printf("ptr1: ");
        for (int i = 0; i < 10; i++) {
            printf("%d ", ptr1[i]);
        }
        printf("\n");

        printf("ptr2: ");
        for (int i = 0; i < 20; i++) {
            printf("%d ", ptr2[i]);
        }
        printf("\n");
    }

    my_free(ptr1);
    my_free(ptr2);

    return 0;
}

说明:

  • buff数组是用于存储分配的内存块的总空间。

  • MemoryBlock结构体用于记录每个内存块的起始位置和大小。

  • my_malloc函数用于分配指定大小的内存块,在memoryBlocks数组中找到一个空闲块或分配一个新块,并返回其起始地址。

  • my_free函数用于释放先前分配的内存块,在memoryBlocks数组中查找要释放的块,并将其大小设置为0。

  • main函数中,通过调用my_malloc来分配内存块,并通过调用my_free来释放内存块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/926357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

718. 最长重复子数组

718. 最长重复子数组 原题链接&#xff1a;完成情况&#xff1a;题解&#xff1a;方法一&#xff1a;动态规划方法二&#xff1a;滑动窗口方法三&#xff1a;二分查找 哈希 原题链接&#xff1a; 718. 最长重复子数组 https://leetcode.cn/problems/maximum-length-of-repe…

XSS盲打练习(简单认识反射型、存储型XSS和cookie欺骗)

文章目录 挖掘cms网站XSS漏洞利用XSS平台盲打CMS&#xff0c;获取后台管理cookiecookie欺骗登录管理员账户 挖掘cms网站XSS漏洞 来到cms网站主页&#xff0c;发现有一个搜索框&#xff0c;输入任意内容后搜索&#xff0c;发现内容会回显&#xff0c;这里可能存在反射型XSS漏洞…

python爬虫11:实战3

python爬虫11&#xff1a;实战3 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论&#xff0c;并不会对网站产生不好…

springboot整合modbus4J(一)

springboot整合modbus4J 1. 介绍 (1) modbus poll&#xff1a;modbus主机仿真器&#xff0c;用于测试和调试modbus从设备。该软件支持modbus rtu、ASCII、TCP/IP。用来帮助开发人员测试modbus从设备&#xff0c;或者其它modbus协议的测试和仿真。它支持多文档接口&#xff0c…

阿里云服务器和腾讯云服务器折扣对比_哪家折扣低?

阿里云服务器和腾讯云服务器根据购买时长可以享受一定的优惠折扣&#xff0c;综合对比下来腾讯云折扣更低&#xff0c;阿腾云来对比下阿里云和腾讯云的云服务器根据购买时长可以享受的常规折扣对比&#xff1a; 目录 阿里云和腾讯云折扣对比 阿里云服务器常规折扣 腾讯云服…

逃出Verifier 无限蓝屏

逃出Verifier 无限蓝屏 前情提要&#xff1a;今天由于在处理 终止代码&#xff1a;WDF_VIOLATION 的蓝屏时&#xff0c;看到网上有用Verifier 来处理这个问题&#xff0c;但是按照方法处理后导致了Verifier无限蓝屏&#xff0c;重启就蓝屏&#xff0c;最后是进入安全模式操作&a…

软件测试及数据分析处理实训室建设方案

一 、系统概述 软件测试及数据分析处理是软件开发过程中的一项重要测试活动&#xff0c;旨在验证不同软件模块或组件之间的集成与交互是否正常。综合测试确保各个模块按照设计要求正确地协同工作&#xff0c;以实现整个软件系统的功能和性能。以下是软件测试及数据分析处理的一…

数据通信——TCP(三次握手及基础特性)

引言 TCP&#xff08;传输控制协议&#xff09;&#xff0c;不像之前的UDP那样&#xff0c;因为这个协议要将很多复杂的东西&#xff0c;所以这次的特性是简单的特性&#xff0c;后续会讲一些复杂难懂的知识&#xff0c;这次先说一些TCP明显的特性 面向连接 TCP提供了对连接的管…

[论文分享]TSPTM-survey:时间序列预训练模型研究综述

目录 1 概要 1.1 贡献点 2 背景 2.1 时序挖掘(TSM)任务 2.2 时间序列的深度学习模型 2.3 预训练模型优势 3 TS-PTMS 概述 3.1 监督预训练 3.1.1 基于分类的预训练 3.1.1.1 通用编码器 3.1.1.2 对齐编码器 3.1.1.3 模型重编程 3.1.1.4 总结 3.1.2 基于预测的预训练…

线性代数(五) 线性空间

前言 《线性代数(三) 线性方程组&向量空间》我通过解线性方程组的方式去理解线性空间。此章从另一个角度去理解 空间是什么 大家较熟悉的&#xff1a;平面直角坐标系是最常见的二维空间 空间由无穷多个坐标点组成 每个坐标点就是一个向量 反过来&#xff0c;也可说&…

泡泡玛特回应头部IP营收增速放缓:IP上市时间不固定

8月23日&#xff0c;针对今年上半年头部IP营收增速放缓问题&#xff0c;泡泡玛特&#xff08;09992.HK&#xff09;管理层在业绩会上解释称&#xff0c;每个IP上市时间并不固定&#xff0c;单从上半年看同比增长会有偏差&#xff0c;而随着下半年两个新系列的推出&#xff0c;全…

Sql Server 数据库事务与锁,同一事务更新查询锁的变化

我有一个People表&#xff0c;有三行数据&#xff1a; 如果我们没详细了解数据库事务执行加锁的过程中&#xff0c;会不会有这样一个疑问&#xff1a;如下的这段 SQL 开启了事务&#xff0c;并且在事务中进行了更新和查询操作。 BEGIN TRAN update People set Name张三 where …

AI绘画工具MJ新功能有点东西,小白也能轻松一键换装

先看最终做出来的效果 直接来干货吧。Midjourney&#xff0c;下面简称MJ 1.局部重绘功能来袭 就在前两天&#xff0c;MJ悄咪咪上线了这个被众人期待的新功能&#xff1a;局部重绘。 对于那些追求创新和个性化的设计师来说&#xff0c;局部绘制不仅是一个实用的功能&#xff…

Smartbi电子表格软件版本更新,首次推出Excel轻应用和语音播放

Smartbi电子表格软件又又又更新啦&#xff01; 此次更新&#xff0c;首次推出了新特性——Excel轻应用和语音播报。另外&#xff0c;还对产品功能、Demo示例、配套文档进行了完善和迭代。 低代码开发Excel轻应用 可实现迅速发布web应用 业务用户的需求往往都处于“解决问题”…

无涯教程-进程 - 简介

进程间通信就是在不同进程之间传播或交换信息&#xff0c;那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的&#xff0c;一般而言是不能互相访问的&#xff0c;唯一的例外是共享内存区。另外&#xff0c;系统空间是“公共场所”&#xff0c;各进…

重磅!云智慧监控宝这些功能免费用啦

自云智慧推出监控宝以来&#xff0c;各行业领域反映强烈&#xff0c;现已有超过24万人次使用监控宝官网的免费试用功能。得益于诸多企业及用户对监控宝热情的持续升温&#xff0c;云智慧释放技术红利&#xff0c;推出监控宝免费使用福利&#xff0c;面向中小型企业提供监控宝核…

YOLO目标检测——耳环数据集下载分享

耳环数据集 耳环数据集是用于研究和分析耳环相关问题的数据集&#xff0c;包含了各种不同类型和风格的耳环图像&#xff0c;共同2600张高清图片 数据集点击下载&#xff1a;YOLO耳环数据集2600图片.rar

如何利用链路追踪快速定位问题

“中浩&#xff0c;xxx接口报错了你看一下咋回事” “稍等一下哈&#xff0c;我看一下。Xxx组的xxx接口报错了,我们这边直接抛错了” “具体啥问题啊&#xff0c;你看下日志&#xff0c;我去找xxx组的人问一下&#xff0c;现在阻塞流程了啊” “呃。。。对这个接口的请求日志…

WebDAV之π-Disk派盘 + 一刻日记

一刻日记是一款日记、笔记和备忘录应用程序,旨在提供一个简单而专注的日记写作工具。它提供了一个干净、直观的界面,允许用户记录和管理他们的日常事务、个人情感、成就和目标等内容。 一刻日记的主要功能包括: – 创建和编辑日记、用户可以撰写和编辑自己的日记,记录重要…

腾讯云服务器租用价格表_一年、1个月和1小时报价明细

腾讯云服务器租用费用表&#xff1a;轻量应用服务器2核2G4M带宽112元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、云服务器CVM S5实例2核2G配置280.8元一年、GPU服务器GN10Xp实例145元7天&#xff0c;腾讯云服务器网长期更新腾讯云轻量…