如何保证申请内存的地址是4的倍数

为了满足每次内存申请的首地址为4的倍数,本文提出了一种简单的方法,即通过封装malloc和free。在申请内存时,额外申请4个字节以确保返回地址对齐,并记录地址偏移量以便正确释放内存,避免内存泄露。这种方法避免了自定义内存池的复杂性,提供了一个实用的解决方案。

       前两天遇到了一个需求: 是每次申请一块内存空间 需要的首地址必须要是4的倍数

      于是瞬间就想到了这不是就是在应用层重新封装一下malloc 和free 嘛,或者你自己实现一个应用层的内存池自己来管理内存空间的地址分配,等等 实现方法很多,使用者的需求就是只要我申请到的空间我可以使用并且给我返回的首地址必须是4的倍数,于是c语言的结构体内存对齐,以及malloc和free的实现方式以及stl内存池以及其他内存池实现的方式都会成为我们实现这个需求的参考。

      思考良久最终选择了一个最简便的方式,就是通过封装malloc和free 于是我们需要考虑最主要的问题是:

     1.怎样保证申请内存是4的倍数

      于是我们想到可以找到当前申请到的内存地址最近的4的倍数的内存地址作为我们返给上层使用这个接口的地址 也就是比如我们当前的地址是0 我们就直接返回  是1 就返回1+3=4   2 就返回2+2=4 等等   但是这样中间的一些内存就不会被使用到 并且用户得到的内存空间不够,于是我们要在用户申请内存空间的基础上多申请4个空间,这样通过多余的这4个空间来保证用户可以得到地址是4的倍数。

     2.如何释放

     那么当前malloc 和free 知道的地址是自己真正得到的地址,我们给用户的地址是真正申请空间中的一部分,这个地址如果直接传给free就会造成4个字节内存泄露。于是我们想到了貌似free在释放空间的时候在一个地方记录过这个空间的大小,要不free怎么知道释放多少,哈哈哈,于是我们想到了再一开始我们就将地址的偏移量记录一下,在释放的时候再次根据偏移量来找到真正要释放的地址。


  下面是我实现的代码,本来想画图讲解一下的,但是最近比较忙,时间紧迫,记录一下,希望其他人有更好的实现方式多多交流哈。

/*************************************************************************
	> File Name: malloc_free.c
	> Author: weeks
	> Mail: 18402927708@163.com
	> Created Time: Sun 03 Dec 2017 01:53:56 PM CST
 ************************************************************************/

#include<stdio.h>
#include <stdlib.h>
#define  NUM  4

void* my_malloc(size_t size) {
    if (size == 0) {
        return NULL; 
    }
    size_t real_size = size + NUM;
    void* reall_addr = malloc(real_size);
    if (reall_addr == NULL) {
        return NULL;
    }
    void* return_addr = reall_addr + (NUM - ((size_t)reall_addr % NUM));
    unsigned char *record = ((unsigned char*)return_addr-1);
    *record = (unsigned char)(NUM - ((size_t)reall_addr % NUM));
    printf("reall_addr: 0x%x\n",reall_addr);
    printf("return_addr: 0x%x\n",return_addr);
    printf("record: %u\n",*record);
    return return_addr;
}

void my_free(void *addr) {
    if (addr == NULL) {
        return ; 
    }
    unsigned char record = *((unsigned char*)addr-1); 
    printf("record: %u\n",record);
    void* reall_addr = (void*)((unsigned char*)addr-record);
    printf("reall_addr: 0x%x\n",reall_addr);
    free(reall_addr);
}

#define SIZE 17
int main()
{
    void *p = my_malloc(SIZE);
    unsigned char* arr = (unsigned char*)p;
    unsigned char i=0;
    for (; i<SIZE; i++) {
      arr[i] = i; 
    printf("arr[%u]=%u ",i,arr[i]); 
    }
    printf("\n"); 
    my_free(p);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值