动态存储分配

一、前言

     C语言中不允许动态定义数组类型长度。前面程序中的数组长度是预先定义好的,在整个程序中是固定不变的。在实际编程中一般不能预先确定数据所需内存空间的大小。利用C语言的内存管理函数,可以根据实际需要动态的分配内存空间或回收释放空闲空间,合理有效的利用内存资源。

二、实验要求

     从键盘输入两个集合La和Lb,将所有在线性表Lb中但不存在La中的数据元素插入到La中

三、代码实现

sqlist.h

主要包含头文件以及定义的重命名还有模版

#pragma once
#include <iostream>
#include <malloc.h>  //malloc等管理内存函数
#include <process.h> //exit函数

using namespace std;

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef int Boolean;       //布尔类型
typedef int ElemType;

#define LIST_INIT_SIZE 10   //线性表存储空间的初始分配量
#define LISTINCREMENT 2     //线性表存储空间的分配增量

typedef struct
{
	ElemType* elem;  //存储空间基质
	int length;      //当前长度
	int listsize;    //当前分配的存储量以(sizeof(ElemType)为单位
}SqList;

//采用线性表的动态分配顺序存储

int InitList(SqList* L);  //初始化
int ListLength(SqList L);
int GetElem(SqList L, int i, ElemType* e);
int LocateElem(SqList L, ElemType e,int(*compare)(ElemType,ElemType));
int ListInsert(SqList* L, int i, ElemType e);
int ListTraverse(SqList L, void (*vi)(ElemType*));
int equal(ElemType c1, ElemType c2);
void Union(SqList* La, SqList Lb);  
void print(ElemType* c);      //打印




sqlist.cpp

具体函数的实现

#include "sqlist.h"
//采用线性表的动态分配顺序存储结构
int InitList(SqList* L) //初始化
{
   	//构造一个空的线性表
    //分配10个int型单元,储存空间基质赋给结构体elem单元
    (*L).elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if (!(*L).elem)
    {
        exit(OVERFLOW);  //分配空间失败
    }
    (*L).length = 0;     //空表长度为零
    (*L).listsize = LIST_INIT_SIZE;//初始储存容量
    return OK;
}

//顺序线性表长度
int ListLength(SqList L)
{
    //当顺序表L存在,返回长度
    return L.length;
}

//获取线性表里面的元素
int GetElem(SqList L, int i, ElemType* e)
{
    //线性表L存在, 用e返回l中第i个元素的值·
    if (i <1 || i>L.length)
        exit(ERROR);
    *e = *(L.elem + i - 1);
    return OK;
}

//确定位置
int LocateElem(SqList L, ElemType e, int(*compare)(ElemType, ElemType))
{
  /*初始条件,顺序表L存在,compare()是数据元素的判定函数(1满足,否则0)*/
  /*返回L中第一个与e满足关系的compare()数据元素的位序*/
    ElemType* p;
    int i = 1; //i初始值为第一个元素
    p = L.elem; //p的初始值为第一元素的存储位置
    while (i <= L.length && !compare(*p++, e))
    {
        ++i;
    }
    if (i <= L.length)
    {
        return i;
    }
    else
    {
        return 0;
    }
    
}
int ListInsert(SqList* L, int i, ElemType e)
{
    /*顺序表L的i个位置插入新的元素,长度+1*/
    ElemType *newbase, * q, * p;
    if (i<1 || i>(*L).listsize)//当前存储空间已满,增加分配
    {
        newbase = (ElemType*)realloc((*L).elem, ((*L).listsize + LISTINCREMENT) * sizeof(ElemType));
        if (!newbase)  //储存分配失败
        {
            exit(OVERFLOW);
        }
        (*L).elem = newbase; //新的基质
        (*L).listsize += LISTINCREMENT;//增加存储容量
    }
   q = (*L).elem + i - 1; //插入位置
    for (p = (*L).elem + (*L).length - 1; p >= q; --p)
    {
        *(p + 1) = *p;
    }
        *q = e;//插入e
        ++(*L).length;
        return OK;     
   
}
int ListTraverse(SqList L, void(*vi)(ElemType*))
{
    //线性表L存在,以此对L的每一个元素调用vi(),一旦vi()失败,这操作失败
    //vi()的形参用“&”表明可以通过vi()改变元素值
    ElemType* p;
    p = L.elem;
    for (int i = 1; i <= L.length; i++)
    {       
        vi(p++);
    }
    cout << "\n";
    return OK;
}
int equal(ElemType c1, ElemType c2)
{
    if (c1 == c2)
    {
        return TRUE;
    }
    else
        return FALSE;
}
void Union(SqList* La, SqList Lb)  //将在Lb元素,不在La的插入La中
{
    ElemType e;
    int La_len, Lb_len;
    La_len = ListLength(*La);
    Lb_len = ListLength(Lb);
    for (int i = 1; i <= Lb_len; i++)
    {
        GetElem(Lb, i, &e);
        if (!LocateElem(*La, e, equal))
        {
            ListInsert(La, ++La_len, e);
        }
    }
}
void print(ElemType* c)     //打印
{ 
    cout << *c++ <<"  ";
}


main.cpp

程序的主函数,具体函数的运用

#include "sqlist.h"


int main()
{
	SqList La, Lb;
	int i, j;
	i = InitList(&La);
	if (i == 1)
	{
		for (j = 1; j <= 5; j++)    //在La表中插入5个元素
		{
			i = ListInsert(&La, j, j);
		}
	}
	cout << "La=";
	ListTraverse(La,print);

	InitList(&Lb);
	for (j = 1; j <= 5; j++)    //在La表中插入5个元素
	{
		i = ListInsert(&Lb, j, 2*j);
	}
	cout << "Lb=";
	ListTraverse(Lb, print);
	Union(&La, Lb);
	cout << "NEW La=";
	ListTraverse(La, print);
	return 0;
}

四、常用函数

1.分配内存空间mlalloc

1)调用形势: (类型说明符)malloc(size) 

      例:

L.data = (ElemType*)malloc(sizeof(ElemType * InitSize))

2)功能:在内存的动态存储区中分配一块长度为size字节的连续区域。函数的返回值为该区域的首地址

3)“类型说明符”表示把该区域用于何种数据类型指针。malloc函数返回一个指针,需要强制转化为自己所定义元素类型指针

p = (char*)malloc(100)

表示分配100字节的内存空间,并强制转换位字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。

2.释放内存空间函数free

    1.调用形式:free(void* ptr);

    2.功能释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量它所指向被释放区域的首地址。被释放区是由malloc或者calloc函数所分配的区域。

此外还有两种分配空间的函数realloc和calloc,在此就不过多赘述。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开开心累兮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值