关于c语言的struct问题和Allocate memory创建空间的问题。

Python018

关于c语言的struct问题和Allocate memory创建空间的问题。,第1张

card *make_card(int suit, int value) {

card *result = malloc(sizeof(card))

result->suit = suit

result->value = value

return result

}

其实是很基础的东西啊。应该只是一时没想到吧。

做过一次以后应该就明白了。

malloc() 函数用来动态地分配内存空间,其原型为:void* malloc (size_t size)

说明:

【参数说明】

size 为需要分配的内存空间的大小,以字节(Byte)计。

【函数说明】

malloc() 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。如果希望在分配内存的同时进行初始化,请使用 calloc()() 函数。

【返回值】

分配成功返回指向该内存的地址,失败则返回 NULL。

操作:

由于申请内存空间时可能有也可能没有,所以需要自行判断是否申请成功,再进行后续操作。

如果 size 的值为 0,那么返回值会因标准库实现的不同而不同,可能是 NULL,也可能不是,但返回的指针不应该再次被引用。

注意:函数的返回值类型是 void *,void 并不是说没有返回值或者返回空指针,而是返回的指针类型未知。所以在使用 malloc() 时通常需要进行强制类型转换,将 void 指针转换成我们希望的类型,例如:

#include<stdlib.h>

typedef int ListData

ListData *data //存储空间基址

data = ( ListData * ) malloc( 100 * sizeof ( ListData ) )

扩展资料

实现malloc的方法:

(1)数据结构

首先我们要确定所采用的数据结构。一个简单可行方案是将堆内存空间以块的形式组织起来,每个块由meta区和数据区组成,meta区记录数据块的元信息(数据区大小、空闲标志位、指针等等)。

数据区是真实分配的内存区域,并且数据区的第一个字节地址即为malloc返回的地址 。

(2)寻找合适的block

现在考虑如何在block链中查找合适的block。一般来说有两种查找算法:

First fit:从头开始,使用第一个数据区大小大于要求size的块所谓此次分配的块

Best fit:从头开始,遍历所有块,使用数据区大小大于size且差值最小的块作为此次分配的块

两种方式各有千秋,best fit有较高的内存使用率(payload较高),而first fit具有较高的运行效率。这里我们采用first fit算法。

(3)开辟新的block 

如果现有block都不能满足size的要求,则需要在链表最后开辟一个新的block。

(4)分裂block 

First fit有一个比较致命的缺点,就是可能会让更小的size占据很大的一块block,此时,为了提高payload,应该在剩余数据区足够大的情况下,将其分裂为一个新的block。

(5)malloc的实现

有了上面的代码,我们就可以实现一个简单的malloc.注意首先我们要定义个block链表的头first_block,初始化为NULL;另外,我们需要剩余空间至少有BLOCK_SIZE+8才执行分裂操作

由于我们需要malloc分配的数据区是按8字节对齐,所以size不为8的倍数时,我们需要将size调整为大于size的最小的8的倍数。

/********************************

内存管理模拟程序

*******************************/

#include<iostream.h>

#include<stdio.h>

#include<math.h>

#include<stdlib.h>

#include <time.h>

#include <windows.h>

/*定义宏*/

#define TotalMemSize 1024 /*划分的物理块的大小,地址范围0~1023*/

#define MinSize 2 /*规定的不再分割的剩余分区的大小*/

#define getpch(type) (type*)malloc(sizeof(type))

/*定义内存块*/

typedef struct memBlock

{

struct memBlock *next/*指向下一个块*/

int stAddr /*分区块的初始地址*/

int memSize /*分区块的大小*/

int status/*分区块的状态,0:空闲,1:以被分配*/

}MMB

/*定义全局变量*/

MMB *idleHead=NULL/*空闲分区链表的头指针*/

MMB *usedHead=NULL/*分配分区链表的头指针*/

MMB *usedRear=NULL/*分配分区链表的链尾指针*/

MMB *np/*循环首次适应算法中指向即将被查询的空闲块*/

int idleNum=1/*当前空闲分区的数目*/

int usedNum=0/*当前已分配分区的数目*/

MMB *memIdle=NULL/*指向将要插入分配分区链表的空闲分区*/

MMB *memUsed=NULL/*指向将要插入空闲分区链表的已分配分区*/

int flag=1/*标志分配是否成功,1:成功*/

/*函数声明*/

void textcolor (int color)/*输出着色*/

void InitMem()/*初始化函数*/

int GetUseSize(float miu,float sigma)/*获得请求尺寸*/

MMB *SelectUsedMem(int n)/*选择待释放的块*/

void AddToUsed()/*将申请到的空闲分区加到分配分区链表中*/

int RequestMemff(int usize)/*请求分配指定大小的内存,首次适应算法*/

int RequestMemnf(int usize)/*请求分配指定大小的内存,循环首次适应算法*/

void AddToIdle()/*将被释放的分配分区加到空闲分区链表中(按地址大小)*/

void ReleaseMem()/*释放指定的分配内存块*/

/*主函数*/

void main()

{

int sim_step

float miu,sigma/*使随机生成的请求尺寸符合正态分布的参数*/

int i

int a

MMB *p

/* double TotalStep=0,TotalSize=0,TotalRatio=0,TotalUSize=0,Ratio=0,n=0

double aveStep=0,aveSize=0,aveRatio=0

int step=0,usesize=0*/

textcolor(11)

printf("\n\t\t内存管理模拟程序\n\n")

/* InitMem()*/

while(true)

{

double TotalStep=0,TotalSize=0,TotalRatio=0,TotalUSize=0,Ratio=0,n=0

double aveStep=0,aveSize=0,aveRatio=0

int step=0,usesize=0

InitMem()

textcolor(12)

printf("\n\n首次适应算法: 0")

printf("\n循环首次适应算法: 1\n")

textcolor(11)

printf("\n请选择一种算法:")

scanf("%d",&a)

textcolor(15)

printf("\n输入一定数量的步数:(sim_step)")

scanf("%d",&sim_step)

printf("\n 输入使随机生成的请求尺寸符合正态分布的参数:miu,sigma ")

scanf("%f,%f",&miu,&sigma)

for(i=1i<=sim_stepi++)

{

textcolor(10)

printf("\n\n#[%d]\n",i)

do{

usesize=GetUseSize(miu,sigma)

while((usesize<0)||(usesize>TotalMemSize))

{

usesize=GetUseSize(miu,sigma)

}

textcolor(13)

printf("\n\n申请的内存尺寸为:%d",usesize)

printf("\n此时可用的空闲分区有 %d 块情况如下:",idleNum)

p=idleHead

textcolor(15)

while(p!=NULL)

{

printf("\n始址:%d\t 尺寸:%d",p->stAddr,p->memSize)

p=p->next

}

TotalSize+=usesize

if(a==0)

step=RequestMemff(usesize)

else

step=RequestMemnf(usesize)

TotalStep+=step

n++

}while(flag==1)

p=usedHead

while(p!=NULL)

{

TotalUSize+=p->memSize

printf("\n始址:%d\t 尺寸:%d",p->stAddr,p->memSize)

p=p->next

}

textcolor(11)

if(TotalUSize!=0)

{

Ratio=TotalUSize/TotalMemSize

TotalUSize=0

printf("\n内存利用率NO.%d :%f%c",i,100*Ratio,'%')

}

else

{

Ratio=0

printf("\n内存利用率NO.%d :%c%c",i,'0','%')

}

TotalRatio+=Ratio

ReleaseMem()

}

if(n!=0)

{

textcolor(10)

aveStep=TotalStep/n

aveSize=TotalSize/n

aveRatio=TotalRatio/sim_step

printf("\n平均搜索步骤:%f",aveStep)

printf("\n平均请求尺寸:%f",aveSize)

printf("\n平均内存利用率:%f",aveRatio)

}

}

}

// 输出着色 /////////////////////////////////////////

void textcolor (int color)

{

SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color )

}

/******************************

函数名:InitMem()

用途:把内存初始化为一整块空闲块

****************************************/

void InitMem()

{

MMB *p

p=getpch(MMB)

p->memSize=TotalMemSize

p->stAddr=0

p->status=0

p->next=NULL

idleHead=p

np=idleHead

usedHead=NULL

usedRear=NULL

idleNum=1

usedNum=0

flag=1

memIdle=NULL

memUsed=NULL

}

/******************************

函数名:GetUseSize(float miu,float sigma)

用途:获得请求尺寸;

参数说明:float miu,float sigma :正态分布的参数

返回值:申请尺寸的大小;

****************************************************/

int GetUseSize(float miu,float sigma)

{

float r1,r2

float u,v,w

float x,y

do

{

r1=rand()/32767.0

r2=rand()/32767.0

u=2*r1-1

v=2*r2-1

w=u*u+v*v

}while(w>1)

x=u*sqrt(((-log(w))/w))

y=v*sqrt(((-log(w))/w))

return miu+sigma*x

}

/******************************

函数名:*SelectUsedMem(int n)

用途:选择待释放的块(0~n-1)

返回值:指向待释放的块的指针;

****************************************************/

MMB *SelectUsedMem(int n)

{

MMB *p

int i,j

if(n>0)

{

i = rand()%n

textcolor(5)

printf("\n\n当前已分配分区总数为:%d",n)

printf("\n待释放块的序号为:%d\n",i )

p=usedHead

if(p!=NULL)

{

for(j=ij>0j--)

p=p->next

return(p)

}

else

return(NULL)

}

else

{

printf("\n当前没有可释放的资源!\n")

}

}

/******************************

函数名:AddToUsed()

用途:将申请到的空闲分区加到分配分区链表中

***************************************************************/

void AddToUsed()

{

MMB *p

memIdle->status=1

if(usedHead==NULL)

{

usedHead=memIdle

usedRear=usedHead

}

else

{

usedRear->next=memIdle

usedRear=memIdle

}

usedNum++

printf("\n当前分配分区共有%d块!",usedNum)

p=usedHead

while(p!=NULL)

{

printf("\n始址:%d \t 尺寸:%d",p->stAddr,p->memSize)

p=p->next

}

}

/******************************

函数名:RequestMemff(int usize)

参数说明:usize:请求尺寸的大小;

用途:请求分配指定大小的内存,首次适应算法

返回值:搜索步骤

***************************************************************/

int RequestMemff(int usize)

{

MMB *p1,*p2,*s

int step

int suc=0

int size1,size2

if(idleHead==NULL)

{

flag=0

textcolor(12)

printf("\n分配失败!")

return 0

}

else

{

if((idleHead->memSize)>usize)

{

size1=(idleHead->memSize)-usize

if(size1<=MinSize)

{

memIdle=idleHead

idleHead=idleHead->next

memIdle->next=NULL

idleNum--

}

else

{

s=getpch(MMB)

s->memSize=usize

s->stAddr=idleHead->stAddr

s->status=1

s->next=NULL

memIdle=s

idleHead->memSize=idleHead->memSize-usize

idleHead->stAddr=idleHead->stAddr+usize

}

step=1

flag=1

textcolor(12)

printf("\n分配成功!")

AddToUsed()

}

else

{

p1=idleHead

step=1

p2=p1->next

while(p2!=NULL)

{

if((p2->memSize)>usize)

{

size2=(p2->memSize)-usize

if(size2<=MinSize)

{

p1->next=p2->next

memIdle=p2

memIdle->next=NULL

idleNum--

}

else

{

s=getpch(MMB)

s->memSize=usize

s->stAddr=p2->stAddr

s->status=1

s->next=NULL

memIdle=s

p2->memSize=p2->memSize-usize

p2->stAddr=p2->stAddr+usize

}

flag=1

suc=1

textcolor(12)

printf("\n分配成功!")

AddToUsed()

p2=NULL

}

else

{

p1=p1->next

p2=p2->next

step++

}

}

if(suc==0)

{

flag=0

textcolor(12)

printf("\n分配失败!")

}

}

}

return step

}

/******************************

函数名:AddToIdle()

用途:将被释放的分配分区加到空闲分区链表中(按地址递增顺序排列)

***************************************************************/

void AddToIdle()

{

MMB *p1,*p2

int insert=0

if((idleHead==NULL))

{

idleHead=memUsed

idleNum++

np=idleHead

}

else

{

int Add=(memUsed->stAddr)+(memUsed->memSize)

if((memUsed->stAddr<idleHead->stAddr)&&(Add!=idleHead->stAddr))

{

memUsed->next=idleHead

idleHead=memUsed

idleNum++

}

else

{

if((memUsed->stAddr<idleHead->stAddr)&&(Add==idleHead->stAddr))

{

idleHead->stAddr=memUsed->stAddr

idleHead->memSize+=memUsed->memSize

}

else

{

p1=idleHead

p2=p1->next

while(p2!=NULL)

{

if(memUsed->stAddr>p2->stAddr)

{

p1=p1->next

p2=p2->next

}

else

{

int Add1=p1->stAddr+p1->memSize

int Add2=p2->stAddr-memUsed->memSize

if((Add1==memUsed->stAddr)&&(memUsed->stAddr!=Add2))

{

p1->memSize=p1->memSize+memUsed->memSize

}

if((Add1!=memUsed->stAddr)&&(memUsed->stAddr==Add2))

{

p2->memSize=p2->memSize+memUsed->memSize

p2->stAddr=memUsed->stAddr

}

if((Add1!=memUsed->stAddr)&&(memUsed->stAddr!=Add2))

{

memUsed->next=p2

p1->next=memUsed

if(np->stAddr==p2->stAddr)

np=p1->next

idleNum++

}

if((Add1==memUsed->stAddr)&&(memUsed->stAddr==Add2))

{

p1->memSize=p1->memSize+memUsed->memSize+p2->memSize

p1->next=p2->next

if((np->stAddr)==(p2->stAddr))

np=p1

idleNum--

}

p2=NULL

insert=1

}

}

if(insert==0)

{

p1->next=memUsed

idleNum++

}

}

}

}

}

/******************************

函数名:ReleaseMem()

用途:释放指定的分配内存块

***************************************************************/

void ReleaseMem()

{

MMB *q1,*q2

MMB *s

if(usedNum==0)

{

printf("\n当前没有分配分区!")

return

}

else

{

s=SelectUsedMem(usedNum)

if(s!=NULL)

{

if(s->stAddr==usedHead->stAddr)

{

memUsed=usedHead

usedHead=usedHead->next

memUsed->next=NULL

AddToIdle()

usedNum--

}

else

{

q1=usedHead

q2=q1->next

while(q2!=NULL)

{

if(q2->stAddr!=s->stAddr)

{

q1=q1->next

q2=q2->next

}

else

{

q1->next=q2->next

memUsed=q2

memUsed->next=NULL

if(q1->next==NULL)

usedRear=q1

AddToIdle()

usedNum--

q2=NULL

}

}

}

}

}

}

/******************************

函数名:RequestMemnf(int usize)

参数说明:usize:请求尺寸的大小;

用途:请求分配指定大小的内存,循环首次适应算法

返回值:搜索步骤

***************************************************************/

int RequestMemnf(int usize)

{

MMB *p2,*p,*s

int step

int iNum=0

int suc=0

int size1,size2,size3

if(idleHead==NULL)

{

flag=0

printf("\n分配失败!")

return 0

}

else

{

iNum=idleNum

while(iNum>0)

{

iNum--

if((np->memSize)>usize)

{

/*指针指向的空闲块满足条件,且正好为头指针*/

if(np->stAddr==idleHead->stAddr)

{

size1=(idleHead->memSize)-usize

if(size1<=MinSize)

{

memIdle=idleHead

idleHead=idleHead->next

memIdle->next=NULL

idleNum--

}

else

{

s=getpch(MMB)

s->memSize=usize

s->stAddr=idleHead->stAddr

s->status=1

s->next=NULL

memIdle=s

idleHead->memSize=idleHead->memSize-usize

idleHead->stAddr=idleHead->stAddr+usize

}

if((idleHead==NULL)||(idleHead->next==NULL))

np=idleHead

else

np=idleHead->next

}

else/*指针指向的空闲块满足条件,不为头指针*/

{

size2=(np->memSize)-usize

if(size2<=MinSize) /*从空闲链表中删除*/

{

p=idleHead

while(p->next->stAddr!=np->stAddr)

p=p->next

p->next=np->next

memIdle=np

memIdle->next=NULL

np=p

idleNum--

}

else

{

s=getpch(MMB)

s->memSize=usize

s->stAddr=np->stAddr

s->status=1

s->next=NULL

memIdle=s

np->memSize=np->memSize-usize

np->stAddr=np->stAddr+usize

}

if(np->next==NULL)

np=idleHead

else

np=np->next

}

step=1

flag=1

suc=1

textcolor(12)

printf("\n分配成功!")

AddToUsed()

iNum=0

}

else /*当前指针指向的空闲区不满足条件*/

{

step=1

p2=np->next

if(p2==NULL)

{

np=idleHead

iNum--

}

else

{

if((p2->memSize)>usize)

{

size3=(p2->memSize)-usize

if(size3<=MinSize)

{

np->next=p2->next

memIdle=p2

memIdle->next=NULL

idleNum--

}

else

{

s=getpch(MMB)

s->memSize=usize

s->stAddr=p2->stAddr

s->status=1

s->next=NULL

memIdle=s

p2->memSize=p2->memSize-usize

p2->stAddr=p2->stAddr+usize

}

flag=1

suc=1

printf("\n分配成功!")

AddToUsed()

if(p2->next==NULL)

np=idleHead

else

np=p2->next

p2=NULL

iNum=0

}

else

{

np=np->next

p2=p2->next

iNum--

step++

}

}

}

//iNum--

}

if(suc==0)

{

flag=0

textcolor(12)

printf("\n分配失败!")

}

}

return step

}