• 详解C语言中内存分配函数


    6217760-b69377db74a51180.jpg

    很多新学C语言的童鞋在用到动态内存分配的时候,对选择哪种分配函数及其有何区别搞不清楚,那么下文就认真的讲讲它们的种种。

    (1)C语言的内存分配方式

    • 从静态存储区域分配
      这些在程序编译的时候就已经分配好,且在程序的整个运行期间都固定不变。

    使用这种方式分配内存空间的数据主要包括:
    代码段(DATA Section)的程序自身语句文本(包括嵌在代码里的字符串常量),已经初始化的全局变量静态变量

    .BSS段的未初始化的全局变量

    • 在栈stack上分配

    这种方式由系统自动分配,函数退出时也由系统自动释放。

    使用这种方式分配内存空间的数据主要包括:
    本地变量函数参数

    • 从堆heap上分配,亦称动态内存分配

    程序在运行的时候用malloc类或new动态申请的内存,由用户自己负责用free或delete释放。动态内存的生存期由用户决定,使用非常灵活,但问题也最多。

    使用这种方式分配内存空间的数据主要包括:
    自定义输入缓存用于接收用户输入数据的变量(数组、结构体等)

    (2)跟内存申请相关的函数

    void* malloc(size_t size)

    作用:从堆中分配size个字节的空间,成功则返回空间首地址,失败则返回空指针。它的声明位于stdlib.h头文件中。

    我们在编程中必须注意分配失败的情况,以使程序更加健壮和完备。所以一般会对其进行包装:

            void *
    xmalloc (size_t size)
    {
        void *value = malloc (size);
        if (value == 0)
            fatal ("virtual memory exhausted");
        return value;
    }
    
          

    同时,由于它并没有对分配的空间进行任何操作,因此基本上malloc之后,需要调用函数memset来初始化。

            struct foo *ptr;
    ...
    ptr = (struct foo *) malloc (sizeof (struct foo));
    if (ptr == 0) 
        abort ();
    memset (ptr, 0, sizeof (struct foo));
    
          

    void * calloc (size_t count, size_t eltsize)

    作用:从堆中分配size个字节的已经清零的空间,成功则返回空间首地址,失败则返回空指针。它的声明位于stdlib.h头文件中。

    它的实现等同于:

            void *
    calloc (size_t count, size_t eltsize)
    {
        size_t size = count * eltsize;
        void *value = malloc (size);
        if (value != 0)
            memset (value, 0, size);
        return value;
    }
    
          

    void * realloc (void *ptr, size_t newsize)

    作用:用来对之前申请的动态内存重新进行分配大小(扩容或缩小)。

    参数解释:ptr必须为之前通过malloc或calloc等函数申请的动态内存首地址;newsize为你现在需要的大小。

    注意事项:
    1 如果是扩容,它不能保证后加的空间一定是接在原来申请的内存空间之后的,因为有可能其之后的空间已经被使用了。此时系统会找一块大小符合你要求的连续空间,并同时把原来空间内容复制到新空间,最后再释放原空间。

    2 如果扩容失败,则原空间内容不受影响。

    3 如果参数ptr为空,则其动作同malloc。

    但是当我们使用时,为了程序的健壮性和完备性,在使用时我们需要包装一下:

            void *
    xrealloc (void *ptr, size_t size)
    {
        void *value = realloc (ptr, size);
        if (value == 0)
            fatal ("Virtual memory exhausted");
        else
            return value;
    
          

    void * reallocarray (void *ptr, size_t nmemb, size_t size)

    该函数作用及各参数同realloc,唯一的不同是当发生乘法溢出时,会进行错误提示。

    void * aligned_alloc (size_t alignment, size_t size)

    作用:函数分配一个地址alignment对齐的大小为size的内存空间。

    参数解释:alignment代表地址对齐参数,必须为2的倍数,且size也必须是alignment的倍数。
    如果分配成功则返回内存首地址,否则返回空,同时依据错误原因设置错误代码errno为ENOMEN或EINVAL

  • 相关阅读:
    JSP引擎的工作原理
    Hibernate缓存配置
    理解LinkedHashMap
    如何在CMD下运用管理员权限
    sun.misc.BASE64Encoder找不到jar包的解决方法
    访问WEB-INF目录中的JSP文件
    Servlet Filter(过滤器)、Filter是如何实现拦截的、Filter开发入门
    message from server: "Host 'xxx' is not allowed to connect to this MySQL server的解决
    深入Java单例模式
    (八)路径(面包屑导航)分页标签和徽章组件
  • 原文地址:https://www.cnblogs.com/leon1124/p/14039772.html
Copyright © 2020-2023  润新知