动态内存分配函数

Posted xiaobaizzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态内存分配函数相关的知识,希望对你有一定的参考价值。

void指针

void用在函数定义中可以表示函数没有返回值或者没有形参,用在这里表示指针指向的数据的类型是未知的。

void*表示一个有效指针,它确实指向实实在在的数据,只是数据的类型尚未确定,在后续使用过程中一般要进行强制类型转换。

malloc()函数:动态分配内存空间

原型:void* malloc(size_t size);

作用:malloc()在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。如果希望在分配内存的同时进行初始化,请使用calloc()函数。

返回值:分配成功返回指向该内存的地址,失败则返回NULL

初始化:使用memset(str, 0, 20);初始化

#include<stdio.h>
#include<iostream>

int main(){
    //分配可以保存30个字符的内存,并把返回的指针转换为char*
    char *str = (char *)malloc(sizeof(char) * 30);
    str = "leetcode" ;
    cout << str << endl;
    return 0;
}

malloc背后的实现原理---内存池

malloc()和free()的分配算法:
技术图片

内存池:

不管具体的分配算法是怎样的,为了减少系统调用,减少物理内存碎片,malloc()的整体思想是先向操作系统申请一块大小适当的内存,然后自己管理,这就是内存池(Memory Pool)。

调用malloc()发生了什么?

内存控制块数据结构,用于管理所有的内存块:is_available标志该块是否可用 + size标志该块的大小

实现malloc时要用到linux下的全局变量:指向进程堆底的指针,也就是指向堆中的第一个内存块 + 指向进程堆顶的指针,也就是指向堆中最后一个内存块的末地址。

1.对堆中的内存块进行遍历,找合适的内存块:判断该块是否可用;大小是否满足要求。

2.没有找到满足条件的内存块时:向操作系统申请新的内存块,返回内存块的首地址。

calloc()函数:分配内存空间并初始化

原型:void* calloc(size_t num, size_t size);

作用:calloc()在内存中动态分配num个长度为size的连续空间,并将每一个字节都初始化为0。所以它的结果是分配了num * size个字节长度的内存空间,并且每个字节的值都是0。

返回值:分配成功返回值指向该内存的地址,失败则返回NULL。

#include<iostream>
#include<stdio.h>
using namespace std;

int main(){
    //分配可以保存30个字符的内存,并把返回的指针转换为char*
    char *str = (char *)calloc(sizeof(char), 30);
    cout << str << endl;
    str = "leetcode" ;
    cout << str << endl;
    return 0;
}

realloc()函数:重新分配内存空间

原型:void* realloc(void* ptr, size_t size)

作用:realloc()对ptr指向的内存重新分配size大小的空间。如果size的值为0,那么ptr指向的内存空间就会被释放,但是由于没有开辟新的内存空间,所以会返回空指针;类似于调用free()

free()函数:

原型:void free(void* ptr);

作用:free()只能释放动态分配的内存,并不能释放任意的内存

注意:free()不会改变ptr变量本身的值,调用free()后它仍然会指向相同的内存空间,但是此刻内存已无效,不能被使用,所以建议将ptr的值设置为NULL。

以上是关于动态内存分配函数的主要内容,如果未能解决你的问题,请参考以下文章

简单动态内存分配实现(附代码)

C语言中动态内存分配函数的用法及作用?(比如malloc,calloc,realloc等)

动态内存分配与静态内存分配

在C语言中,如何给函数分配内存?

C语言中的动态内存分配的用法举例

在C语言中,如何给函数分配内存?