文章教程

全国计算机等级考试二级C语言10.3关于动态存储的函数

8/22/2020 10:24:52 PM 人评论 次浏览

10.3 关于动态存储的函数

众所周知,构成链表结构的每一个节点,是在需要时由系统自动分配存储的,即在需要时才开辟一个节点的存储单元。C语言编译系统是如何动态地开辟和释放存储单元的呢?在C语言的库函数中有以下有关函数。

考点4 malloc()函数

真考链接

考点4 偏难,属于重点理解内容。在选择题中考核概率为40%。在操作题中,主要以修改题的形式进行考查,考核概率为10%。

ANSIC标准规定 malloc()函数返回值的类型为 void*。

函数的调用形式为:

malloc(size)

其中,size的类型为unsigned int。

功能:malloc()函数用来分配size个字节的存储区,返回一个指向存储区首地址的基类型为void的地址。若没有足够的内存单元供分配,则函数返回空(NULL)。

在ANSIC中,malloc()函数返回的地址为void*(无值型),所以在调用函数时,必须利用强制类型转换将其转换成所需的类型。此处括号中的*号不可少。

由动态分配得到的存储单元没有名字,只能靠指针变量来引用它。一旦指针改变指向,原存储单元及所存数据都将无法再引用。通过调用malloc()函数所分配的动态存储单元中没有确定的初值。

一般情况下,若不能确定数据类型所占字节数,可以使用sizeof运算符来求得。这是一种常用的形式,它由系统来计算指定类型的字节数。

真题精选

【例1】有以下程序:

#include<stdio.h>

#include<stdlib.h>

int fun(int n)

{ int *p;

p =(int *)malloc(sizeof(int));

*p = n;

return *p;

main()

{ int a;

a = fun(10);

printf("% d\n",a + fun(a));

程序的运行结果是(  )。

A.0    B.10    C.20    D.出错

【答案】C

【解析】分配内存空间函数malloc()的调用形式:(类型说明符*)malloc(size)。其功能是在内存的动态存储区中分配一块长度为“size”字节的连续区域,函数的返回值为该区域的首地址。“类型说明符”表示把该区域用于何种数据类型。

【例2】下列给定程序中已建立一个带头节点的单向链表,链表中的各节点按节点数据域中的数据递增有序链接。函数fun()的功能是:把形参 x的值放入一个新节点并插入链表中,使插入后各节点数据域中的数据仍保持递增有序。

请在标号处填入正确的内容,使程序得出正确的结果。

注意:部分源程序给出如下。不得增行或删行,也不得更改程序的结构。

试题程序

#include <stdio.h>

#include <stdlib.h>

#define N 8

typedef struct list

{ int data;

struct list *next;

}SLIST;

void fun(SLIST *h,int x)

{ SLIST *p,*q,*s;

s=(SLIST *)malloc(sizeof(SLIST));

s->data=【1】;

q=h;

p=h->next;

while(p!=NULL && x>p->data){

q=【2】;

p=p->next;

s->next=p;

q->next=【3】;

SLIST *creatlist(int *a)

{ SLIST *h,*p,*q;int i;

h = p =(SLIST *)malloc(sizeof (SLIST));

for(i=0;i<N;i++)

{ q =(SLIST *)malloc(sizeof (SLIST));

q->data=a[i];p->next=q;p=q;

p->next=NULL;

return h;

void outlist(SLIST *h)

{ SLIST *p;

p=h->next;

if(p==NULL)

printf("\nThe list is NULL!\n");

else

{ printf("\nHead");

do {printf("->% d",p->data);

p=p->next;}while(p!=NULL);

printf("->End\n");

main()

{ SLIST *head;int x;

int a[N] ={11,12,15,18,19,22,25,29};

head=creatlist(a);

printf("\nThe list before inserting:\n");

outlist(head);

printf("\nEnter a number:");

scanf("% d",&x);

fun(head,x);

printf("\nThe list after inserting:\n");

outlist(head);

【答案】【1】x 【2】p 【3】s

【解析】本题考查:malloc()函数;链表的基本操作。了解链表的基本思想和相关算法,理解有关链表插入及删除时指针移动的先后顺序问题,注意指针的保存和归位。

标号【1】:将形参x赋值给节点的数据域。

标号【2】和标号【3】:将新的节点和原有链表中的节点进行比较。

考点5 free()函数

真考链接

考点5 偏难,属于重点理解内容。考核概率为 10%。在操作题中,主要以修改题的形式进行考查,考核概率为10%。

函数原型为:

void free(void *p);

该函数的功能是释放由 p所指向的那段内存空间,使这段存储空间能为他用。p是最近一次调用malloc()或calloc()函数时返回的值。

注意:free()函数无返回值。

常见问题

为什么对于曾经使用动态存储来进行分配的指针变量,要在程序结束前,全部用free()函数释放?

因为在程序结束前,全部用free()函数释放可以节约内存,同时要保证内存的安全管理。

真题精选

以下程序的输出结果是(  )。

#include <stdio.h>

void fut(int **s,int p[2][3])

{**s=p[1][1];}

main()

{ int a[2][3] ={1,3,5,7,9,11 },*p;

p=(int *)malloc(sizeof(int));

fut(&p,a);

printf("% d\n",*p);

free(p);

A.1    B.7    C.9    D.11

【答案】C

【解析】函数fut()中,形参s是一个指向指针的指针,它接受一个基类型为int的指针的地址;p是一个行指针,它可以指向一个二维数组的起始行,此二维数组每行只能有3个元素。在fut()函数的语句"**s=p[1][1];"中,可知p [1][1]的值为9。在主函数中,定义p是一个基类型为int的指针,通过调用malloc()函数,在内存中分配了一个int类型的存储单元,并把其地址赋给了p,使它指向此存储单元。调用语句"fut(&p,a);",把指针p的地址传给了形参s,使s指向了指针p。在fut()函数中,语句"**s=p[1][1];"赋值号的左边,s中放的是主函数中指针p的地址,**s则代表主函数中指针p所指动态分配的存储单元;"**s=p[1][1];"就是把9赋给此动态存储单元。主函数中printf中的输出项是*p,即输出p所指动态存储单元中的值。输出结果为9。总结:malloc()函数是在程序运行、调用该函数时,在内存开辟指定字节的存储单元。malloc()函数返回一个void类型的地址值,因此,若要把此地址赋给基类型为int的指针pi就必须进行强制类型转换,如pi=(int*)malloc(sizeof(int)),而不能直接写成pi=malloc(sizeof(int))。同理,若要把此地址赋给基类型为double的指针pd,就应当写成pd=(double*)malloc(sizeof(double))。强制类型转换时不能把*号丢掉,如把调用语句写成(int)malloc(sizeof (int)),以至要求把指针类型转换为整型,这是不允许的。

教程类别