首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

代码在运行到一半后会失误,希望大家帮忙改改

2013-12-22 
代码在运行到一半后会出错,希望大家帮忙改改这是heap.h#ifndef HEAP_H#define HEAP_Hvoid * my_malloc(uns

代码在运行到一半后会出错,希望大家帮忙改改
这是heap.h

#ifndef HEAP_H
#define HEAP_H

void * my_malloc(unsigned int size);
void my_free(void * addr);
void printList();//调试用
#endif
这是heap.cpp
#include "heap.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>   //memset(...)
//堆空间heap初始大小
#define HEAP_SIZE 1024*1024
//空闲块切割后若剩余不超过RESIDUE,则不进行切割
#define RESIDUE 8
//对用户请求分配的堆空间大小进行对齐,保证分配的内存块为2^ALIGN的倍数
#define ALIGN 2
#define ROUND(s) (((1<<ALIGN)-1)+s)&(~((1<<ALIGN)-1))
//
static char heap[HEAP_SIZE];//用一个字符数组来模拟堆
static int init = 0;//是否已经初始化
//
struct Linker{
unsigned int size;
unsigned int available;
struct Linker * next;
struct Linker * rptr;
struct Linker * lptr;
} * first = (struct Linker *)&heap;




/******************************************************************
 * 初始化堆栈
 ******************************************************************/
static void initialHeap(){
memset(first,0,HEAP_SIZE);
first->next = NULL;
/*****************************************************************
分配时,如果需要可把next域所占位置也分配,size域不被破坏即可.
所以计算空闲块大小时,可把next域也计入
******************************************************************/

first->size = HEAP_SIZE-sizeof(int);   

}
/*****************************************************************
 * 申请堆空间,返回分配到的内存首地址,分配失败则返回NULL
 *
 *****************************************************************/
void * my_malloc(unsigned int size){
/*
请补全此函数中代码
*/
void * memory_location;//分配的内存块的首地址
Linker *next;//下一个内存块
Linker *current;
current = first;
int int_current_address = (int)current;
int int_next_address = 0;
while (current != NULL)//开始遍历所有的内存块
{
if (current->available != 0)//该块内存未被使用
{
if (current->size>size && (current->size - size)>RESIDUE)//该块内存大小符合,并且可以将该块内存切割
{
int_next_address = int_current_address + sizeof(Linker)+size;//转换为int型,保证地址按+1计算(步长为1)
next = (Linker*)int_next_address;
int old_size = current->size;
current->available = 0;//已经分配,不再可用
current->size = size;//分配的大小
current->rptr = next;//下一个内存块地址
next->lptr = current;//已经分配的内存块地址
next->available = 1;
next->size = old_size - sizeof(Linker)-size;
next->rptr = NULL;
memory_location = (void *)(int_current_address + sizeof(Linker));//链表的首地址,加上链表自身占据的大小,得到可用块的首地址
return memory_location;
}
if (current->size >= size && (current->size - size) <= RESIDUE)//分配内存后,剩余的内存块过小,不再切割
{
current->available = 0;
memory_location = (void *)(int_current_address + sizeof(Linker));
return memory_location;
}
if (current->size<size)//该块内存空间太小
{
current = current->rptr;//测试下一块内存
int_current_address = (int)current;
}
}
else
{
current = current->rptr;//测试下一块内存
int_current_address = (int)current;
}
}
return NULL;
}
//要求one的首地址小于two
static void mergeIfAdjacent(struct Linker * one, struct Linker * two){
if(one > two){
struct Linker * tmp = one;
one = two;
two = tmp;
printf("one > two\n");
}
char * cptr = (char *)one;
if(cptr + one->size + sizeof(int) == (char *) two){
one->size += two->size + sizeof(int);
one->next = two->next;
}
}
/**************************************************************
 * 释放已经分配的堆空间
 *
 **************************************************************/
void my_free(void * addr){
/*
请补全此函数中代码
*/
Linker *current, *temp;
int linkaddress;
current = (Linker*)addr;
linkaddress = (int)current - sizeof(Linker);
temp = (Linker *)linkaddress;

memset(current, 0, temp->size);//刷新内存块内容为0
current = temp;
current->available = 1;//恢复可用状态
while (current->rptr != NULL)//有后续内存块
{
if (current->rptr->available == 1)//后续内存块空闲,合并
{
if (current->rptr->rptr != NULL)//后续内存块还有后续,则应该修改其左指针
{
current->rptr->rptr->lptr = current;//被合并的内存块的后续内存块的左指针指向新内存块
}
current->size += current->rptr->size + sizeof(Linker);//更新可用块大小,加上后续内存块的大小
current->rptr = current->rptr->rptr;//改右指针 
}
else


{
break;
}
}
while (current->lptr != NULL)//有前置内存块
{
if (current->lptr->available == 1)//前置内存块空闲
{
if (current->rptr != NULL)//
{
current->rptr->lptr = current->lptr;//修改左指针
}
current->lptr->size += current->size + sizeof(Linker);//更新前置内存块的大小
current->lptr->rptr = current->rptr;
current = current->lptr;
}
else
{
break;
}
}
}
/**********************************************************************
用于测试

 **********************************************************************/
void printList(){
if(!init){
init = 1;
initialHeap();
}
struct Linker * cur = first;
for(; cur != NULL; cur = cur->next){
printf("[%x,%d]",(int)(cur),cur->size);
if(cur->next)
printf("-->");
else
printf("\n");
}
}

测试代码main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "heap.h"

#define ALLOC(n) printf("void * ptr%d = my_malloc(%d)\n",(n),(n));\
void * ptr##n = my_malloc(n);\
printList();
#define FREE(n) printf("my_free(ptr%d)\n",(n));\
my_free(ptr##n);\
printList();

int main(){
printList();

printf("**************begin mallocing memory*****************\n");
ALLOC(16);
ALLOC(32);
ALLOC(48);
ALLOC(64);
ALLOC(80);

printf("**************begin freeing memory*****************\n");

FREE(32);
FREE(64);
FREE(16);
FREE(48);
FREE(80);
return 0;
}
希望帮忙看看是那里出错了,帮忙改一下
[解决办法]

static void initialHeap(){
    memset(first, 0, HEAP_SIZE);
    first->next = NULL;
    /*****************************************************************
    分配时,如果需要可把next域所占位置也分配,size域不被破坏即可.
    所以计算空闲块大小时,可把next域也计入
    ******************************************************************/

    first->size = HEAP_SIZE - sizeof(int);
    first->available = 1;

}

热点排行