如何实现动态分配,malloc,realloc,calloc的使用方法,数组,链表,结构体实现动态分配(含代码实现)

这篇具有很好参考价值的文章主要介绍了如何实现动态分配,malloc,realloc,calloc的使用方法,数组,链表,结构体实现动态分配(含代码实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如何实现动态分配,malloc,realloc,calloc的使用方法,数组,链表,结构体实现动态分配(含代码实现)

🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏

🪔本系列专栏 -  数据结构与算法_勾栏听曲_0

🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️

📌个人主页 - 勾栏听曲_0的博客📝

🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆

🎇善治病者,必医其受病之处;善救弊者,必塞其起弊之源。📈

目录

动态分配

意义

动态分配与静态分配内存的异同于优缺点

何时需要动态分配

动态分配函数

malloc

calloc

realloc

三者的异同

数组中的动态分配

结构体中的动态分配

链表中的动态分配


动态分配

意义

        在计算机科学中, 动态内存分配(Dynamic memory allocation)又称为堆内存分配,是指计算机程序在运行期中分配使用内存。它可以当成是一种分配有限内存资源所有权的方法。

        动态分配的内存在被程序员明确释放或垃圾回收之前一直有效。与静态内存分配的区别在于没有一个固定的生存期。这样被分配的对象称之为有一个“动态生存期”。

        动态分配的意义是为了让程序能够根据运行时的需要,灵活地分配和释放内存空间,以提高内存利用率和程序的功能性。动态分配可以解决以下问题:

        当程序运行时,无法确定变量(如数组、结构体、链表等)的大小或个数时,静态分配的内存空间可能不够或浪费,而动态分配可以根据实际情况分配合适的空间。

        当程序运行时,需要频繁地创建和销毁变量时,静态分配的内存空间可能造成内存碎片或不足,而动态分配可以及时释放不用的空间,避免内存泄漏。

        当程序运行时,需要将变量的生命周期延长到函数调用结束后时,静态分配的局部变量会在函数返回时被销毁,而动态分配的变量可以保持有效,直到被释放。

动态分配与静态分配内存的异同于优缺点

        动态分配与静态分配的异同与优缺点如下:

        异:

                静态分配是编译器完成的,比如局部变量的分配。动态分配是程序运行时由程序员通过函数(如malloc、calloc等)进行分配。

                静态分配的内存空间是在栈上分配的,生命周期和作用域受函数限制。动态分配的内存空间是在堆上分配的,生命周期和作用域由程序员控制。

                静态分配的内存空间是连续的,大小和个数在编译时确定。动态分配的内存空间是不连续的,大小和个数在运行时确定。

        同:

                静态分配和动态分配都是为了给变量或数据结构分配内存空间,以便存储数据和信息1。
静态分配和动态分配都需要遵循一些规则和约束,以保证程序的正确性和安全性。

        优缺点:

                静态分配的优点是简单、快速、安全,不需要手动管理内存空间。缺点是浪费内存空间,不能适应程序运行时的变化。

                动态分配的优点是节省内存空间,能适应程序运行时的变化,能创建复杂的数据结构。缺点是复杂、慢速、危险,需要手动管理内存空间。

何时需要动态分配

        动态分配内存的目的是为了节省内存空间,提高内存利用率,以及适应程序运行时的不确定性1。一般来说,以下情况需要动态分配内存:

                当程序运行时,无法确定变量(如数组、结构体、链表等)的大小或个数时,需要动态分配内存来根据实际情况分配合适的空间。

                当程序运行时,需要频繁地创建和销毁变量时,需要动态分配内存来避免静态分配的内存浪费或不足。

                当程序运行时,需要将变量的生命周期延长到函数调用结束后时,需要动态分配内存来保持变量的有效性。


但是需要注意的是,动态分配由他的好处,同时也有一些弊端:

动态分配内存的好处和坏处如下:

        好处:

                可以根据程序运行时的需要,灵活地分配和释放内存空间,提高内存利用率。

                可以创建一些复杂的数据结构,如链表、树、图等,实现更多的功能。

                可以将变量的生命周期延长到函数调用结束后,避免局部变量的作用域限制。

        坏处:

                需要手动管理内存空间,容易出现内存泄漏、内存碎片、内存溢出等问题。

                动态分配的内存空间通常不连续,可能影响程序的性能和效率。

                动态分配的内存空间可能被其他程序或进程占用或修改,导致程序出错或崩溃

动态分配函数

malloc

        头文件:

#include <stdlib.h>  

        语法格式:

void *malloc(size_t size);

        用法举例:

#include <stdlib.h>  
  
int main() {  
    int *ptr;  
    int n;  
  
    // 动态分配内存空间  
    ptr = (int*) malloc(sizeof(int) * n);  
  
    // 输出动态分配的内存空间大小  
    printf("Dynamically allocated memory size: %d\n", n);  
  
    // 输出动态分配的内存空间地址  
    printf("Dynamically allocated memory address: %p\n", ptr);  
  
    // 输出动态分配的内存空间指针  
    printf("Dynamically allocated memory pointer: %p\n", ptr);  
  
    // 释放动态分配的内存空间  
    free(ptr);  
  
    return 0;  
}

calloc

        头文件:

#include <stdlib.h>  

        语法格式:

                其中,num 表示要分配的元素个数,size 表示每个元素的大小。

void* calloc(size_t num, size_t size);

        用法举例:

                在这个例子中,calloc 函数接受两个参数,num 表示要分配的元素个数,size 表示每个元素的大小。函数返回一个指向分配起始地址的指针,如果分配不成功,则返回 NULL

其中,num 表示要分配的元素个数,size 表示每个元素的大小。

        注意:

                 calloc 函数在分配内存时会先检查分配的内存大小是否足够,如果不足,则会抛出 malloc 函数的 malloc_error 异常。因此,在使用 calloc 函数时,需要确保分配的内存大小足够,否则可能会导致程序崩溃或产生不可预测的行为。

realloc

        头文件:

#include <malloc .h>

        语法格式:

                其中,ptr 是要重新分配内存空间的指针,size 是要分配的内存块的大小。realloc() 函数会在程序运行时动态计算需要分配的内存大小,并返回一个指向动态分配的内存块的指针。如果在分配内存时发生错误,realloc() 函数将返回一个空指针。

void *realloc(void *ptr, size_t size);

三者的异同

相似之处:

  • malloccalloc都可以用于分配动态内存空间,并且都需要传入两个参数,第一个参数是要分配的元素个数,第二个参数是每个元素的大小。
  • malloccalloc都会将分配的内存空间初始化为0,如果分配的内存原来已经被分配过,则其中可能会遗留有各种各样的数据。
  • malloccalloc都可以用于分配指定大小的内存空间,并且返回类型都是void*

不同之处:

  • malloc是从系统堆上分配内存的,而callocrealloc都是在程序运行时动态分配内存空间的。
  • malloc返回的是指向动态分配内存空间的指针,而callocrealloc返回的是指向分配的内存空间的指针。
  • malloccalloc都可以用于扩大或缩小分配的内存空间,而realloc只能用于扩大分配的内存空间。
  • malloccalloc的参数类型不同,malloc接受的是unsigned int类型的参数,而callocrealloc接受的是size_t类型的参数。
  • malloccalloc都需要对返回值进行判空,而realloc不需要。
  • malloc是一个标准库函数,而callocreallocrealloc都是第三方库函数。

数组中的动态分配

  • 声明一个指针或指向指针的指针,作为动态数组的起始地址。
  • 使用 malloc() 或 calloc() 函数为数组分配内存空间,根据数组的维数和元素类型确定所需的字节数。
  • 使用循环或其他方式来为数组中的每个元素进行赋值和访问,注意使用下标或指针运算符。
  • 使用 free() 函数释放数组所占用的内存空间,避免内存泄漏。
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *array = NULL; // 声明一个整型指针
    int len = 10; // 数组长度
    array = (int *)malloc(len * sizeof(int)); // 为数组分配内存空间
    if (array == NULL) // 检查是否分配成功
    {
        printf("动态申请内存失败!\n");
        exit(1);
    }
    for (int i = 0; i < len; i++) // 为数组赋值
    {
        array[i] = i + 1;
    }
    for (int i = 0; i < len; i++) // 打印数组元素的值和地址
    {
        printf("array[%d] = %d, &array[%d] = %p\n", i, array[i], i, &array[i]);
    }
    free(array); // 释放数组内存
    return 0;
}

结构体中的动态分配

        在上面的代码中,我们定义了一个Point结构体,它包含两个整型变量xy。然后,我们使用malloc函数动态分配了一个大小为2Point类型的内存空间,并将其地址赋值给指针变量p.z。最后,我们输出了动态分配的内存空间的大小、地址和指针。

#include <stdio.h>  
  
typedef struct {  
    int x;  
    int y;  
} Point;  
  
int main() {  
    Point p;  
    p.x = 10;  
    p.y = 20;  
  
    // 动态分配内存空间  
    p.z = (Point*) malloc(sizeof(Point) * 2);  
  
    // 输出动态分配的内存空间大小  
    printf("Dynamically allocated memory size: %d\n", sizeof(Point) * 2);  
  
    // 输出动态分配的内存空间地址  
    printf("Dynamically allocated memory address: %p\n", p.z);  
  
    // 输出动态分配的内存空间指针  
    printf("Dynamically allocated memory pointer: %p\n", p.z);  
  
    // 释放动态分配的内存空间  
    free(p.z);  
  
    return 0;  
}

链表中的动态分配

        在上面的代码中,我们定义了一个Node结构体,它包含一个整型变量data和一个指向下一个节点的指针next。然后,我们使用createNode函数动态分配了一个大小为2Node类型的内存空间,并将其地址赋值给指针变量p.z。最后,我们输出了动态分配的内存空间的大小、地址和指针。文章来源地址https://www.toymoban.com/news/detail-426761.html

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct Node {  
    int data;  
    struct Node* next;  
} Node;  
  
Node* createNode(int data) {  
    Node* newNode = (Node*) malloc(sizeof(Node));  
    newNode->data = data;  
    newNode->next = NULL;  
    return newNode;  
}  
  
void printList(Node* head) {  
    while (head != NULL) {  
        printf("%d ", head->data);  
        head = head->next;  
    }  
    printf("\n");  
}  
  
int main() {  
    Node* head = createNode(1);  
    head->next = createNode(2);  
    head->next->next = createNode(3);  
    head->next->next->next = createNode(4);  
  
    printList(head);  
  
    // 动态分配内存空间  
    head->next->next->next = createNode(5);  
  
    printList(head);  
  
    return 0;  
}

到了这里,关于如何实现动态分配,malloc,realloc,calloc的使用方法,数组,链表,结构体实现动态分配(含代码实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】动态内存管理(malloc,free,calloc,realloc,柔性数组)

    本章重点 为什么存在动态内存管理 动态内存函数的介绍 malloc free calloc realloc 常见的动态内存错误 几个经典的笔试题 柔性数组 我们已经掌握的内存开辟方式有: int val = 20; //在栈空间上开辟四个字节 char arr[10] = {0}; 在栈空间上开辟十个字节的连续空间 但是上述开辟空间的方

    2024年02月03日
    浏览(48)
  • C语言——动态内存管理(malloc, calloc, realloc, free, 柔性数组详解)

    我们以往定义数组,都是这么定义的: 以这种方式开辟空间有两个特点: 空间开辟的大小是固定的 数组在声明的时候,必须指定数组的长度,它所需要的内存在编译时分配 因此就导致了这样一个现象:我们无法在后续的过程中修改数组的大小,这是一个十分麻烦的事情 而

    2024年02月16日
    浏览(53)
  • C语言中灵活多变的动态内存,malloc函数 && free函数&& calloc函数 && realloc函数

    铁子们好啊!今天阿辉给大家讲一下C语言里面特别重要的一块知识——动态内存管理,为什么说它重要呢?相信大家在使用数组时都遇到过数字开辟空间太大或者太小的情况,这是很尴尬的因为数组空间一旦确定就难以扩大或者缩小。而今天的动态内存管理将帮我们很好的解

    2024年02月03日
    浏览(39)
  • calloc、malloc、realloc函数的区别及用法

    三者都是分配内存,都是stdlib.h库里的函数,但是也存在一些差异。 (1)malloc函数。其原型void *malloc(unsigned int num_bytes); num_byte为要申请的空间大小,需要我们手动的去计算,如int *p = (int )malloc(20 sizeof(int)),如果编译器默认int为4字节存储的话,那么计算结果是80Byte,一次申请

    2024年02月08日
    浏览(45)
  • C语言 malloc动态内存分配函数

    malloc函数:malloc时动态内存分配函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,就是当数组创建长度不一定 害怕数据存储不够或者不能浪费时间 在使用malloc开辟空间时,使用完成一定要释放空间,如果不释放会造内存泄漏。n在使用ma

    2024年02月07日
    浏览(45)
  • 16 malloc 虚拟内存分配的调试(1)

    呵呵 在 c 语言中 malloc 应该是初学者必须了解的一个函数了吧  但凡 涉及到堆内存分配的相关, 必定会使用到 malloc, realloc, calloc 这几个函数  其中 malloc 最常见, 也是最 实用  在 HotspotVM 中也经常会看到 malloc 的身影  我们这里 来调试一下 malloc 的相关的一些场景  本文主要的

    2023年04月09日
    浏览(43)
  • 从 malloc 分配大块内存失败 来简看 linux 内存管理

    应用进程 malloc 返回了null,但是观察到的os 的free内存还有较大的余量 ,很奇怪为什么会这样? 不可能是oom导致的(当然也没有 os 的oom 日志),free还有余量,系统也没有cgroup的应用隔离。 我们linux上使用的库函数 malloc 基本都是用glibc库实现的malloc函数(当然如果binary 链接

    2024年02月08日
    浏览(53)
  • IP 地址如何进行动态分配?

    由于 IP 地址资源的有限性,大部分用户上网都是使用动态 IP 地址,而不是静态 IP 地址。动态 IP 地址指的是在需要的时候才进行 IP 地址分配的方式,而静态 IP 地址是固定分配一个 IP 地址,每次都用这一个地址。因此,IP 地址动态分配是一种普遍的网络配置方式。 IP 地址动

    2024年01月21日
    浏览(45)
  • 如何在C中动态分配二维数组

    在C语言中如何动态申请连续的二维数组。可以采用多申请一些指针,然后这一些指针分别指向后面数据区中对应的位置,如一个3*4的int类型数组,我们先申请大小为sizeof(int*) * 3 + 3 * 4 * sizeof(int)的一维数组设为arr。然后arr[0]存放指向arr + sizeof(int*) * 3这个位置的指针,arr[1]存放

    2023年04月27日
    浏览(33)
  • 用指针实现内存动态分配

    导引 :已知:变量在使用前必须被定义且安排好存储空间。且变量有这么一些分类:全局变量、静态局部变量【它们的储存一般是在编译时确定,在程序开始执行前完成。】自动变量【在执行进入变量定义所在的复合语句时为它们分配存储,变量的大小也是静态确定的。临时

    2023年04月09日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包