链表的C语言实现(一)

 2024-02-03 00:02:29  阅读 0

准备工作:动态内存分配

1、为什么要使用动态内存分配?

但在我们学习链表之前,如果我们要存储比较大量的相同类型或结构的数据,我们总是使用数组。 例如,如果我们要存储某个班级学生某科的成绩,我们总是定义一个float类型数组(0.5分存在):

浮动分数[30];

然而,在使用数组的时候,总有一个问题困扰着我们:数组应该有多大?

在许多情况下,您不确定要使用多大的数组。 例如,在上面的例子中,你可能不知道班级里有多少学生,所以你必须将数组定义得足够大。 这样,你的程序在运行时就会申请一个你认为足够大的固定大小的内存空间。 即使知道班级的学生人数,如果由于某种特殊原因导致人数增加或减少,就必须再次修改程序,扩大数组的存储范围。 这种分配固定大小内存的方法称为静态内存分配。 但是,这种内存分配方法有严重的缺陷,尤其是在处理某些问题时:大多数情况下会浪费大量的内存空间,而且在少数情况下,当你定义的数组不够大时,可能会导致一旦发生跨境错误,甚至可能导致严重后果。

那么有没有其他方法可以解决此类外部问题呢? 是的,那就是动态内存分配。

所谓动态内存分配是指在程序执行过程中动态分配或回收存储空间的内存分配方法。 动态内存分配不需要像数组等静态内存分配方法那样预先分配存储空间。 而是系统根据程序的需要实时分配,分配的大小就是程序需要的大小。 从上面动态和静态内存分配的对比,我们可以知道动态内存分配相对于晶泰内存分配的特点:

1、无需预先分配存储空间;

2、分配的空间可以根据程序的需要进行扩大或缩小。

2、如何实现动态内存分配和管理

要根据程序的需要动态分配存储空间,必须使用以下函数

1. 功能

函数原型为:

无效*(整数大小)

它的作用是在内存的动态存储区域中分配一块长度为size的连续空间。 它的参数是一个无符号整数,返回值是一个指向分配的连续存储区域起始地址的指针。 还有一点必须注意的是,当函数分配存储空间失败(比如内存不足)时,会返回NULL指针。 因此,在调用该函数时,应检查返回值是否为NULL,并进行相应的操作。

下面的例子是一个动态分配程序:

#

#

主要的()

int 计数,*数组; /*count是计数器,array是整型指针,也可以理解为指向整型数组的首地址*/

if((数组(int *) (10*(int)))==NULL)

(“无法成功分配存储空间。”);

退出(1);

for (count=0;count<10;count ) /*给数组赋值*/

数组[计数]=计数;

for(count=0;count<10;count) /*打印数组元素*/

(“-”,数组[计数]);

在上面的例子中,动态分配了10个整数存储区域,然后分配并打印。 示例中,if((array(int *) (10*(int)))==NULL)语句可以分为以下步骤:

1)分配10个连续的整数存储空间,并返回一个指向其起始地址的整数指针。

2)将此整数指针地址分配给数组

3)检查返回值是否为NULL

2.免费功能

由于内存区域总是有限的,因此不能无限制地分配,程序必须尽力节省资源。 因此,当分配的内存区域不使用时,必须将其释放,以便其他变量或程序可以使用它。 这时候我们就要用到free函数了。

其函数原型为:

无效自由(无效* p)

它的作用是释放指针p指向的内存区域。

它的参数p必须是从先前调用该函数或函数(另一个动态分配存储区域的函数)返回的指针。 将其他值传递给 free 函数很可能会导致崩溃或其他灾难性后果。

注意:这里重要的是指针的值,而不是用于申请动态内存的指针本身。 例子:

int *p1,*p2;

p1=(10*(int));

p2=p1;

……

自由(p2) /*或自由(p2)*/

返回值赋给p1,p1的值赋给p2,所以此时p1和p2都可以作为free函数的参数。

函数分配存储区域。

free函数释放未使用的内存区域。

因此,这两个函数可以实现内存区域的动态分配和简单管理。

标签: 分配 内存 存储

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码