实现动态分配,malloc,realloc,calloc的使用方法,数组,链表,结构体实现动态分配含代码实现
🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏
🪔本系列专栏 - 数据结构与算法_勾栏听曲_0
🍻欢迎大家 🏹 点赞👍 评论📨 收藏⭐️
📌个人主页 - 勾栏听曲_0的博客📝
🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆
🎇善治病者,必医其受病之处;善救弊者,必塞其起弊之源。📈
目录
动态分配
意义
在计算机科学中, 动态内存分配(Dynamic memory allocation)又称为堆内存分配,是指计算机程序在运行期中分配使用内存。它可以当成是一种分配有限内存资源所有权的方法。
动态分配的内存在被程序员明确释放或垃圾回收之前一直有效。与静态内存分配的区别在于没有一个固定的生存期。这样被分配的对象称之为有一个“动态生存期”。
动态分配的意义是为了让程序能够根据运行时的需要,灵活地分配和释放内存空间,以提高内存利用率和程序的功能性。动态分配可以解决以下问题:
当程序运行时,无法确定变量(如数组、结构体、链表等)的大小或个数时,静态分配的内存空间可能不够或浪费,而动态分配可以根据实际情况分配合适的空间。
当程序运行时,需要频繁地创建和销毁变量时,静态分配的内存空间可能造成内存碎片或不足,而动态分配可以及时释放不用的空间,避免内存泄漏。
当程序运行时,需要将变量的生命周期延长到函数调用结束后时,静态分配的局部变量会在函数返回时被销毁,而动态分配的变量可以保持有效,直到被释放。
动态分配与静态分配内存的异同于优缺点
动态分配与静态分配的异同与优缺点如下:
异:
静态分配是编译器完成的,比如局部变量的分配。动态分配是程序运行时由程序员通过函数(如malloc、calloc等)进行分配。
静态分配的内存空间是在栈上分配的,生命周期和作用域受函数限制。动态分配的内存空间是在堆上分配的,生命周期和作用域由程序员控制。
静态分配的内存空间是连续的,大小和个数在编译时确定。动态分配的内存空间是不连续的,大小和个数在运行时确定。
同:
静态分配和动态分配都是为了给变量或数据结构分配内存空间,以便存储数据和信息1。
静态分配和动态分配都需要遵循一些规则和约束,以保证程序的正确性和安全性。
优缺点:
静态分配的优点是简单、快速、安全,不需要手动管理内存空间。缺点是浪费内存空间,不能适应程序运行时的变化。
动态分配的优点是节省内存空间,能适应程序运行时的变化,能创建复杂的数据结构。缺点是复杂、慢速、危险,需要手动管理内存空间。
何时需要动态分配
动态分配内存的目的是为了节省内存空间,提高内存利用率,以及适应程序运行时的不确定性1。一般来说,以下情况需要动态分配内存:
当程序运行时,无法确定变量(如数组、结构体、链表等)的大小或个数时,需要动态分配内存来根据实际情况分配合适的空间。
当程序运行时,需要频繁地创建和销毁变量时,需要动态分配内存来避免静态分配的内存浪费或不足。
当程序运行时,需要将变量的生命周期延长到函数调用结束后时,需要动态分配内存来保持变量的有效性。
但是需要注意的是,动态分配由他的好处,同时也有一些弊端:
动态分配内存的好处和坏处如下:
好处:
可以根据程序运行时的需要,灵活地分配和释放内存空间,提高内存利用率。
可以创建一些复杂的数据结构,如链表、树、图等,实现更多的功能。
可以将变量的生命周期延长到函数调用结束后,避免局部变量的作用域限制。
坏处:
需要手动管理内存空间,容易出现内存泄漏、内存碎片、内存溢出等问题。
动态分配的内存空间通常不连续,可能影响程序的性能和效率。
动态分配的内存空间可能被其他程序或进程占用或修改,导致程序出错或崩溃
动态分配函数
malloc
头文件:
#include <stdlib.h>
语法格式:
void *malloc(size_t size);
用法举例:
-
-
-
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);
三者的异同
相似之处:
malloc
和calloc
都可以用于分配动态内存空间,并且都需要传入两个参数,第一个参数是要分配的元素个数,第二个参数是每个元素的大小。malloc
和calloc
都会将分配的内存空间初始化为0,如果分配的内存原来已经被分配过,则其中可能会遗留有各种各样的数据。malloc
和calloc
都可以用于分配指定大小的内存空间,并且返回类型都是void*
。
不同之处:
malloc
是从系统堆上分配内存的,而calloc
和realloc
都是在程序运行时动态分配内存空间的。malloc
返回的是指向动态分配内存空间的指针,而calloc
和realloc
返回的是指向分配的内存空间的指针。malloc
和calloc
都可以用于扩大或缩小分配的内存空间,而realloc
只能用于扩大分配的内存空间。malloc
和calloc
的参数类型不同,malloc
接受的是unsigned int
类型的参数,而calloc
和realloc
接受的是size_t
类型的参数。malloc
和calloc
都需要对返回值进行判空,而realloc
不需要。malloc
是一个标准库函数,而calloc
、realloc
和realloc
都是第三方库函数。
数组中的动态分配
- 声明一个指针或指向指针的指针,作为动态数组的起始地址。
- 使用 malloc() 或 calloc() 函数为数组分配内存空间,根据数组的维数和元素类型确定所需的字节数。
- 使用循环或其他方式来为数组中的每个元素进行赋值和访问,注意使用下标或指针运算符。
- 使用 free() 函数释放数组所占用的内存空间,避免内存泄漏。
-
-
-
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
结构体,它包含两个整型变量x
和y
。然后,我们使用malloc
函数动态分配了一个大小为2
的Point
类型的内存空间,并将其地址赋值给指针变量p.z
。最后,我们输出了动态分配的内存空间的大小、地址和指针。
-
-
-
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
函数动态分配了一个大小为2
的Node
类型的内存空间,并将其地址赋值给指针变量p.z
。最后,我们输出了动态分配的内存空间的大小、地址和指针。
-
-
-
-
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;
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcikhi
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13