当前位置: 首页 > article >正文

C语言内存管理函数

面试里会遇到让自己编写一个内存管理函数

1. memset 将指定的内存区域的每个字节设置为指定的值

 函数原型:

void *memset(void *s, int c, size_t n);
  • 参数:
    • s: 指向要填充的内存块的指针。
    • c: 要设置的值(会被转换为无符号字符)。
    • n: 要设置的字节数。
  • 用途: 常用于初始化数组或清空内存,例如将一个数组的所有元素设置为 0。
  • 示例:
int arr[5];  
memset(arr, 0, sizeof(arr));  // 将 arr 的所有元素设置为 0

 自己编写:

void *my_memset(void *s, int c, size_t n) {  
    unsigned char *p = s;        // 将 void* 转换为 unsigned char*  
    while (n--) {  
        *p++ = (unsigned char)c; // 设置每个字节  
    }  
    return s;                   // 返回原始指针  
}

2. memcpy 用于复制源内存到目标内存。

  • 函数原型:
    void *memcpy(void *dest, const void *src, size_t n);
  • 参数:
    • dest: 指向目标内存区域的指针(将数据复制到这里)。
    • src: 指向源内存区域的指针(从这里复制数据)。
    • n: 要复制的字节数。

示例

int src[5] = {1, 2, 3, 4, 5};  
int dest[5];  
memcpy(dest, src, sizeof(src));  // 将 src 的内容复制到 dest

自己编写 

void *my_memcpy(void *dest, const void *src, size_t n) {  
    unsigned char *d = dest;     // 目标指针  
    const unsigned char *s = src; // 源指针  
    while (n--) {  
        *d++ = *s++;            // 逐个字节复制  
    }  
    return dest;                // 返回目标指针  
}

3. memmove 用于从一个内存区域复制数据到另一个内存区域,支持内存重叠。

函数原型:

int memcmp(const void *s1, const void *s2, size_t n);

自己编写

void *my_memmove(void *dest, const void *src, size_t n) {  
    unsigned char *d = dest;  
    const unsigned char *s = src;  
    
    if (d < s) {  
        // 正常复制  
        while (n--) {  
            *d++ = *s++;  
        }  
    } else {  
        // 从后向前复制  
        d += n;  
        s += n;  
        while (n--) {  
            *(--d) = *(--s);  
        }  
    }  
    return dest;  
}

4. memcmp 比较两个内存块的内容。

int my_memcmp(const void *s1, const void *s2, size_t n) {  
    const unsigned char *p1 = s1;  
    const unsigned char *p2 = s2;  
    
    while (n--) {  
        if (*p1 != *p2) {  
            return *p1 - *p2; // 返回两个不同字节的差  
        }  
        p1++;  
        p2++;  
    }  
    return 0; // 相等  
}

5. malloc 会请求操作系统分配一定量的内存。一般实现比较复杂,这里给出一个非常简化的版本。

void *my_malloc(size_t size) {  
    void *ptr = sbrk(size); // 使用 sbrk 请求内存(仅用于示例,真实情况下更复杂)  
    return (ptr == (void *)-1) ? NULL : ptr; // 错误处理  
}

6. free 用于释放先前分配的内存。

void my_free(void *ptr) {  
    // 这里通常需要将指针返回内存管理系统  
    // 真实情况下,这需要维护一个内存块的链表或其他结构  
}

7. realloc 是调整动态内存块的大小,通常会先调用 malloc 和 memcpy

void *my_realloc(void *ptr, size_t size) {  
    if (ptr == NULL) {  
        return my_malloc(size); // 如果原指针为 NULL,分配新内存  
    }  
    // 获取原内存块的大小(具体实现中可能需要额外存储大小)  
    size_t old_size = /* ... */;  
    void *new_ptr = my_malloc(size);  
    if (new_ptr) {  
        my_memcpy(new_ptr, ptr, old_size < size ? old_size : size);  
        my_free(ptr); // 释放旧内存  
    }  
    return new_ptr; // 返回新指针  
}


http://www.kler.cn/a/459390.html

相关文章:

  • IM系统在体育直播网站中的重要性
  • java中的基本数据类型有哪些?
  • win32汇编环境,对话框中显示bmp图像文件
  • Docker 安装与配置 Nginx
  • C# 设计模式(结构型模式):装饰器模式
  • 使用 Actix-Web、SQLx 和 Redis 构建高性能 Rust Web 服务
  • [python SQLAlchemy数据库操作入门]-14.实时数据采集 记录股市动态
  • No.2十六届蓝桥杯备战|练习题4道|数据类型|字符型|整型|浮点型|布尔型|signed|unsigned(C++)
  • 下载并使用CICFlowMeter提取网络流特征(Windows版本)
  • Mac 环境 VVenC 编译与编码命令行工具使用教程
  • 英创主板ESM8400支持Debian 12桌面系统
  • CPT203 Software Engineering 软件工程 Pt.1 概论和软件过程(中英双语)
  • Python入门:8.Python中的函数
  • kanzi做3d时钟屏保
  • 【算法day27】动态规划:基础2
  • 微软Win11内核迎新变,Rust语言助力提升系统安全可靠性
  • 第25天:信息收集-项目系统一键打点资产侦察企查产权空间引擎风险监测利器部署
  • 29. 书籍叠放
  • 大模型系列——旋转位置编码和长度外推
  • Django 模型中使用 `UniqueConstraint` 实现唯一性约束
  • 碰一碰发视频后端源码技术开发详解,支持OEM
  • VectorCAST入门指导
  • vue3大屏实现;使用使用CSS Grid实现大屏
  • wxWidgets 3.2.6发布 —— 发布于2024年9月9日
  • 【机器学习】-深度学习模型
  • 计算机网络 (16)数字链路层的几个共同问题