C 语言几个内存管理函数整理

C 语言几个内存管理函数整理

对于常用C/C++语言的人来说,内存管理无疑是十分重要的一个工作,因此经常会用到一些内存管理函数,在这里做一个简单的整理。

mallco

void *malloc(unsigned int num_bytes);

动态内存分配,用于申请一块连续的指定大小的内存块区域以 void* 类型返回分配的内存区域地址,即再分配内存之后,该指针已经保存了一个地址。
void* 类型表示未确定类型的指针,一般需要强制转换为需要的指针类型。

realloc

void *realloc(void *mem_address, unsigned int newsize);

先判断当前的指针是否有足够的连续空间,如果有,扩大 mem_address 指向的地址,并且将mem_address 返回,如果空间不够,先按照 newsize 指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来 mem_address 所指内存区域(注意:原来指针是自动释放,不需要使用 free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

free

void free(void *ptr);

释放 malloc (或 callocrealloc)函数给指针变量分配的内存空间的函数.
注意:free 指针 ptr 指向的内存之后,为了避免之后重新用 free 错误释放这块儿已经释放的内存,一般需要将 ptr=NULL

memset

void *memset(void *s, int ch, size_t n);

s 中当前位置后面的 n 个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法

memcpy

void *memcpy(void *dest, const void *src, size_t n);

从源 src 所指的内存地址的起始位置开始拷贝 n 个字节到目标 dest 所指的内存地址的起始位置中。
这里需要对 memcpy 这个函数做一些说明,memcpy 函数后经常还会有一个 malloc 函数,那么这里就有一个疑问,为什么用memcpy函数拷贝了一份内存之后还要使用 malloc 函数,下面我们就来学习一下。
下面是一个代码片段:

// 定义一个结构体
typedef struct _Test_Data{
    int width;
    int height;
    int* pMyData[2];
}TESTDATA, *PTESTDATA;

    //主函数
int main(){
    int data[] = {1, 2, 3, 4, 5};

    TESTDATA sData1 = {0};
    sData1.width = 5;
    sData1.height = 3;
    sData1.pMyData[0] = data;
    sData1.pMyData[1] = data + 2;

    TESTDATA sData2 = { 0 };
    memcpy(&sData2, &sData1, sizeof(TESTDATA));

    cout << "sData1 address " << &sData1 << endl << "sData2 address " << &sData2 << endl << endl;
    cout << "sData1.width " << sData1.width << endl << "sData2.width " << sData2.width << endl << endl;
    cout << "sData1.height " << sData1.height << endl << "sData2.height " << sData2.height << endl << endl;
    cout << "sData1.pMyData[0] address " << sData1.pMyData[0] << endl << "sData2.pMyData[0] address " << sData2.pMyData[0] << endl << endl;
    cout << "sData1.pMyData[1] address " << sData1.pMyData[1] << endl << "sData2.pMyData[1] address " << sData2.pMyData[1] << endl << endl;


    *(sData2.pMyData[0] + 1) = 15;
    cout << "*(sData1.pMyData[0]+1) " << *(sData1.pMyData[0] + 1)<< endl;
    cout << "*(sData2.pMyData[0]+1) " << *(sData2.pMyData[0] + 1)<< endl <<endl;

    sData2.pMyData[0] = (int*)malloc(5 * sizeof(int));
    memcpy(sData2.pMyData[0], sData1.pMyData[0], 5 * sizeof(int));

    *(sData2.pMyData[0] + 1) = 9;

    cout << "*(sData1.pMyData[0]+1) " << *(sData1.pMyData[0] + 1) << endl;
    cout << "*(sData2.pMyData[0]+1) " << *(sData2.pMyData[0] + 1) << endl;
    return 0;
}

以上代码中,我们先定义了一个结构体变量 sData1,然后使用 memcpy 函数拷贝一份内存到 sData2 变量的首地址处,此时地址模型如下:
sData模型
即此时两个结构体变量的在内存中的地址虽然不一样,但是结构体变量中的成员具有相同的值,这包括,变量 widthheight,以及 pMyData 数组中存放的地址,结果如下:
请添加图片描述
由于 sData1sData2 中的变量共用一块内存,因此改变一个结构体的成员变量时,另一个结构体成员变量的值也会随着改变;
上面代码中设置 *(sData2.pMyData[0] + 1) = 15; 此时,*(sData1.pMyData[0] + 1) 的值也为15,结果如下:
result2
因为 memcpy 函数使得 sData1.pMyData[0]sData2.pMyData[0] 指向同一块内存,因此修改其中给一个的值自然会使得另外一个的值发生改变。因此,在使用 memcpy 拷贝结构体变量时一定要注意,若结构体中有指针成员变量,则应当在 copy 之后为结构体中的指针变量分配内存,然后再使用一次 memcpy 来拷贝内存。
result3
memmove

void *memmove( void* dest, const void* src, size_t count );

src 所指内存区域复制 count 个字节到 dest 所指内存区域。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值