首页 > 系统相关 >C~动态内存函数介绍

C~动态内存函数介绍

时间:2024-11-12 20:19:02浏览次数:3  
标签:arr 函数 int malloc 介绍 分配内存 内存 动态内存 分配

前面咱们与小伙伴们分享了C ~库函数的相关知识,今天咱们再介绍一下动态内存函数~

一.什么是动态内存函数

动态内存函数是指在 C 语言中用于在程序运行时动态分配和释放内存的一系列标准库函数。这些函数定义在 <stdlib.h> 头文件中,主要包括 malloccallocreallocfree,它们允许程序在运行时请求和释放内存,从而提供了灵活性,使得程序可以根据需要分配内存,而不是在编译时静态分配。

二.常用的动态内存函数

1. malloc

malloc 用于动态分配内存。它在程序运行时分配指定大小的内存块,并返回指向这块内存的指针。如果分配失败,malloc 返回 NULL

函数原型
void *malloc(size_t size);

// size:要分配的内存块的大小(以字节为单位)。
//返回值:成功时返回指向分配内存的指针,失败时返回 NULL。
使用示例

以下是一个使用 malloc 函数分配内存的示例:

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int *arr;
    int n = 10; // 假设我们需要一个包含10个整数的数组

    // 使用 malloc 分配内存
    arr = (int *)malloc(n * sizeof(int));

    // 检查 malloc 是否成功分配内存
    if (arr == NULL)
     {
        fprintf(stderr, "Memory allocation failed!\n");
        return 1;
    }

    // 使用分配的内存
    for (int i = 0; i < n; i++)
         {
            arr[i] = i * i; // 存储一些数据
        }

    // 打印数组内容
    for (int i = 0; i < n; i++) 
        {
            printf("%d ", arr[i]);
        }
    printf("\n");

    // 释放分配的内存
    free(arr);

    return 0;
}
注意事项
  1. 类型转换:在 C 语言中,malloc 返回 void* 类型的指针,可以隐式转换为任何其他类型的指针。在 C++ 中,需要显式类型转换。

  2. 内存初始化malloc 分配的内存内容是未初始化的,可能包含任意值。如果需要初始化为零,可以使用 calloc

  3. 内存释放:使用 malloc 分配的内存必须使用 free 函数释放,以避免内存泄漏。

  4. 错误处理:始终检查 malloc 的返回值,以确保内存分配成功。

  5. 内存对齐malloc 分配的内存通常是适当对齐的,可以存储任何类型的数据。

malloc 是动态内存分配的基础函数之一,提供了在运行时分配内存的能力,使得程序能够灵活地管理内存资源。

2.calloc

calloc 是 C 语言标准库中的一个函数,用于动态分配内存并初始化为零。它在程序运行时分配指定数量的元素,每个元素具有指定的大小,并返回指向这块内存的指针。如果分配失败,calloc 返回 NULL

函数原型
void *calloc(size_t num, size_t size);
//  num:要分配的元素数量。
// size:每个元素的大小(以字节为单位)。
//返回值:成功时返回指向分配内存的指针,失败时返回 NULL。
使用示例

以下是一个使用 calloc 函数分配内存的示例:

#include <stdio.h>
#include <stdlib.h>

int main()
 {
    int *arr;
    int n = 10; // 假设我们需要一个包含10个整数的数组

    // 使用 calloc 分配内存并初始化为零
    arr = (int *)calloc(n, sizeof(int));

    // 检查 calloc 是否成功分配内存
    if (arr == NULL) 
    {
        fprintf(stderr, "Memory allocation failed!\n");
        return 1;
    }

    // 使用分配的内存
        for (int i = 0; i < n; i++) 
        {
            arr[i] = i * i; // 存储一些数据
        }
    
    // 打印数组内容
        for (int i = 0; i < n; i++) 
        {
            printf("%d ", arr[i]);
        }
     printf("\n");

    // 释放分配的内存
    free(arr);

    return 0;
}
注意事项
  1. 类型转换:在 C 语言中,calloc 返回 void* 类型的指针,可以隐式转换为任何其他类型的指针。在 C++ 中,需要显式类型转换。

  2. 内存初始化calloc 分配的内存被初始化为零,这意味着所有位都被设置为 0。

  3. 内存释放:使用 calloc 分配的内存必须使用 free 函数释放,以避免内存泄漏。

  4. 错误处理:始终检查 calloc 的返回值,以确保内存分配成功。

  5. 内存对齐calloc 分配的内存通常是适当对齐的,可以存储任何类型的数据。

callocmalloc 的主要区别在于 calloc 会自动初始化分配的内存为零,而 malloc 分配的内存内容是未初始化的,可能包含任意值。这使得 calloc 在需要初始化内存为零时非常有用。

3.realloc

realloc 是 C 语言标准库中的一个函数,用于重新分配内存。它可以扩大或缩小之前分配的内存块,并将内容从旧内存块复制到新内存块。如果新内存块比旧内存块大,新内存块的额外部分将未初始化;如果新内存块比旧内存块小,超出部分将被截断。

函数原型
void *realloc(void *ptr, size_t new_size);
//     ptr:指向之前分配的内存块的指针。
//new_size:新的内存块大小(以字节为单位)。
//   返回值:成功时返回指向新内存块的指针,失败时返回 NULL。
使用示例

以下是一个使用 realloc 函数重新分配内存的示例:

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int *arr;
    int n = 5; // 初始大小
    int new_n = 10; // 新大小

    // 使用 malloc 分配初始内存
    arr = (int *)malloc(n * sizeof(int));
    if (arr == NULL) 
    {
        fprintf(stderr, "Initial memory allocation failed!\n");
        return 1;
    }

    // 使用内存
    for (int i = 0; i < n; i++)
     {
        arr[i] = i * i;

    }

    // 打印初始数组内容
    printf("Initial array: ");
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 使用 realloc 重新分配内存
    arr = (int *)realloc(arr, new_n * sizeof(int));
    if (arr == NULL) 
    {
        fprintf(stderr, "Memory reallocation failed!\n");
        return 1;
    }

    // 使用新内存
    for (int i = n; i < new_n; i++)
     {
        arr[i] = i * i;
     }

    // 打印新数组内容
    printf("Resized array: ");
    for (int i = 0; i < new_n; i++)
     {
        printf("%d ", arr[i]);
     }
    printf("\n");

    // 释放分配的内存
    free(arr);

    return 0;
}
注意事项
  1. 内存释放:如果 realloc 失败并返回 NULL,原始内存块 ptr 仍然有效,不会被释放。因此,在使用 realloc 时,最好使用一个临时指针来保存返回值,以避免内存泄漏。

  2. 内存初始化realloc 不会初始化新分配的内存。如果新内存块比旧内存块大,新内存块的额外部分将未初始化。

  3. 错误处理:始终检查 realloc 的返回值,以确保内存重新分配成功。

  4. 内存对齐realloc 分配的内存通常是适当对齐的,可以存储任何类型的数据。

  5. 内存移动:如果 realloc 需要移动内存块,它会自动处理内存的复制和释放旧内存。

realloc 是一个非常有用的函数,可以在运行时动态调整内存大小,使得程序能够更灵活地管理内存资源。

4.free

free 函数是 C 和 C++ 语言中用于释放动态分配内存的标准库函数。当你使用 malloccallocrealloc 等函数分配内存时,这些内存块会一直占用直到你显式地释放它们。free 函数的作用就是释放之前动态分配的内存,使其可以被操作系统或其他程序再次使用。

函数原型

在 C 语言中,free 函数的原型定义在 <stdlib.h> 头文件中,如下所示:

void free(void *ptr);

//ptr:指向之前通过 malloc、calloc 或 realloc 分配的内存块的指针。
//free 函数没有返回值。
使用示例

下面是一个简单的示例,展示如何使用 malloc 分配内存,并使用 free 释放内存:

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int *array = (int *)malloc(10 * sizeof(int)); // 分配内存
    if (array == NULL) 
     {
        fprintf(stderr, "内存分配失败\n");
        return 1;
    }

    // 使用分配的内存
    for (int i = 0; i < 10; i++) 
      {
        array[i] = i;
      }

    // 打印数组内容
    for (int i = 0; i < 10; i++) 
      {
        printf("%d ", array[i]);
       }
    printf("\n");

    free(array); // 释放内存
    array = NULL; // 避免悬空指针

    return 0;
}
注意事项
  1. 只释放动态分配的内存:不要尝试释放静态分配或自动分配的内存(如局部变量或全局变量)。
  2. 避免重复释放:确保不要多次释放同一块内存,这可能导致未定义行为。
  3. 设置为 NULL:释放内存后,将指针设置为 NULL,以避免悬空指针问题。
  4. 检查 NULL 指针:虽然 free(NULL) 是安全的,但最好在调用 free 之前检查指针是否为 NULL,以提高代码的可读性和健壮性。

正确使用 free 函数对于管理内存和避免内存泄漏至关重要。

三.总结

动态内存函数在 C 和 C++ 编程中扮演着至关重要的角色,它们的主要用途和重要性可以从以下几个方面进行阐述:

用途
  1. 数据结构实现:动态内存管理是实现复杂数据结构(如链表、树、图等)的基础。这些数据结构通常需要在运行时根据需要分配和释放内存。

  2. 处理不确定大小的数据:当程序需要处理的数据大小在编译时无法确定时,动态内存管理允许程序在运行时根据实际需要分配内存。

  3. 内存优化:通过动态分配内存,程序可以仅使用所需的内存量,而不是预先分配大量内存,从而提高内存使用效率。

  4. 灵活性:动态内存管理提供了更大的灵活性,允许程序根据运行时的条件和需求动态调整内存使用。

重要性
  1. 资源管理:正确管理内存资源是确保程序稳定运行的关键。不当的内存管理可能导致内存泄漏、程序崩溃甚至系统不稳定。

  2. 性能优化:通过精确控制内存的分配和释放,可以优化程序的性能,减少不必要的内存占用,提高程序的响应速度和处理能力。

  3. 避免内存浪费:静态内存分配可能会导致大量内存浪费,因为静态分配的内存大小在编译时就已经确定,而动态内存管理可以根据实际需要分配内存,减少浪费。

  4. 适应性:动态内存管理使得程序能够更好地适应不同的运行环境和数据规模,提高了程序的适应性和可扩展性。

  5. 错误处理:动态内存管理函数通常提供错误处理机制,如分配失败时返回 NULL,这允许程序在内存分配失败时进行适当的错误处理,而不是直接崩溃。

  6. 内存泄漏检测:在开发过程中,动态内存管理函数的使用可以帮助开发者检测和修复内存泄漏问题,这对于长期运行的程序尤为重要。

总之,动态内存函数是 C 和 C++ 程序设计中不可或缺的工具,它们提供了必要的灵活性和控制能力,使得开发者能够有效地管理内存资源,编写出高效、稳定且可扩展的程序。

以上就是关于动态内存函数的所有分享,希望能给小伙伴们带来帮助,最后祝愿所有小伙伴们早日达到自己的目标@

标签:arr,函数,int,malloc,介绍,分配内存,内存,动态内存,分配
From: https://blog.csdn.net/Code_Allen/article/details/143722323

相关文章

  • 用函数实现模块化程序设计三
    函数的嵌套调用C语言的函数定义是互相平行的、独立的,也就是说,在定义函数时,一个函数内不能再定义另一个函数,也就是不能嵌套定义,但是可以嵌套调用函数,也就是说,在调用一个函数的过程中,又调用另一个函数如上执行过程:执行main函数遇到函数调用的语句,调用函数a,流程转到a函数......
  • Scratch自制积木(自定义函数)求最小公倍数
    在Scratch编程环境中,自制积木是一种用户定义的代码块,它可以将复杂的脚本简化为更易于理解和管理的部分。通过自制积木,用户可以将一系列指令封装成一个单独的积木块,从而方便地在不同的项目中重用这些指令。Scratch自制积木功能是一个强大且灵活的工具,它可以帮助用户更好地组织......
  • HTML静态网页成品作业(HTML+CSS)——游戏战地介绍设计制作(4个页面)
    ......
  • Java常用方法:StringUtils.isNotBlank()、StringUtils.isEmpty()、去除空格的函数、手
    Java常用方法:StringUtils.isNotBlank()、StringUtils.isEmpty()、去除空格的函数、手机号中间4位换成*、判断字符是否为数字要使用工具类StringUtils,首先得导入依赖<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><ve......
  • 深⼊理解指针(5)[回调函数、qsort相关知识(qsort可用于各种类型变量的排序)】
     目录1.回调函数2.qsort相关知识(qsort可用于各种类型变量的排序)一   回调函数    1定义/作用:把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅......
  • [RuoYi二次开发]RuoYi管理系统功能介绍
     目录一、前言1、RuoYi-Vue简介2、RuoYi-Vue主要特性二、若依管理系统功能介绍2.1首页 2.2系统管理 用户管理页面字典管理 菜单页面岗位管理部门管理  2.3系统监控 在线用户定时任务服务监控 2.4系统工具表单创建代码生成系统接口三、总结 ......
  • 11.12,pythpn函数
    函数:一、什么是函数定义:函数是组织好,可重复使用,用来实现单一,或关联功能的代码段二、pycharm中的表结构项目,包(init)或目录,py文件,py文件包含多个函数或类等三、函数的有哪些优点?1、降低代码冗余2、增加代码的复用性,提高开发效率3、提高程序的拓展性4、封装:就是把代码片段放......
  • T113平台tina5摄像头TVIN开发连载(1)-TVIN摄像头驱动介绍及硬件准备
    SBC-T113S产品特性:采用Allwinner公司Cortex-A7双核T113-S3/S4处理器,运行最高速度为1.2GHZ;内置64-bitXuanTieC906RISC-V协处理器(仅T113-S4支持);支持JPEG/MJPEG视频编码,最大分辨率1080p@60fps;支持多格式1080P@60fps视频解码(H.265,H.264,MPEG-1/2/4);支持RGB666/LVDS/MIPI-......
  • 【C++】详细介绍模版进阶,细节满满
    目录一、非类型模版参数:1、介绍:2、使用:3、注意:4、应用二、模版特化(一)、概念(二)、函数模版特化1、步骤:2、举例:3、不建议使用函数模版特化(三)、类模版特化1.全特化:2、偏特化2.1、部分特化2.2、参数更进一步的限制2.3、注意:2.4、普通指针变量传递给const指针变量......
  • 电子电器装配制造行业MES系统解决方案介绍
    一、行业背景与挑战电子电器装配制造行业涵盖了家用电器、消费电子、智能家居设备等多种产品,产品品类丰富且技术更新迅速。随着消费者对产品多样性和高品质的需求不断提升,电子电器企业需具备高效的生产管理能力以快速应对市场需求。该行业生产流程复杂,涉及精密的装配和检测......