c - CS:APP Malloc Lab - 为什么我的代码应该只执行一次却重复了 12 次?
问题描述
我是一名使用在线资料独自学习 CS:APP3e(计算机系统:程序员视角)的学生。我在 Malloc Lab 工作,遇到了无法调试的问题。我编写了自己的显式空闲列表分配器,它适用于诸如short1、short2、coalescing 之类的简单跟踪。但是,它会在诸如binary2.rep之类的较长跟踪上出现段错误。
该设计遵循 CS:APP 教科书的铭文:双字对齐,每个块最少 3 个双字(=24 字节),空闲块的“pred”和“succ”指针。我按 LIFO 顺序维护列表。
使用我自己的跟踪,我发现它何时在binary2.rep上出现段错误。跟踪文件如下所示:
1024100 /* Unused number */
12000 /* Number of IDs */
16000 /* Number of operations */
1 /* Unused number */
a 0 16 /* allocate 16 bytes. Job ID = 0 */
a 1 112 /* allocate 112 bytes. Job ID = 1 */
a 2 16
a 3 112
a 4 16
a 5 112
(...)
它旨在交替调用 malloc(16) 和 malloc(112)。在第 694 次调用之前,我的显式空闲列表分配器执行没有错误。从第 695 次调用开始,我的代码开始生成错误消息“损坏的大小与 prev_size”。从 800-something 调用中,我的代码段错误而没有产生任何错误消息。
为了弄清楚发生了什么,我添加了一个全局变量
int cnt = 0;
每次调用 mm_malloc() 时都会增加它,并打印它。我发现:mm_malloc() 被调用了 12 倍。
我期待以下日志:
extend_heap:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [4096:f] pred: [(nil)] succ: [(nil)] footer: [4096:f]
0xf6154020: EOL
CNT: 1
place:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
mm_malloc:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
extend_heap:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [4096:f] pred: [(nil)] succ: [(nil)] footer: [4096:f]
0xf6154020: EOL
但是得到了以下结果:
extend_heap:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [4096:f] pred: [(nil)] succ: [(nil)] footer: [4096:f]
0xf6154020: EOL
CNT: 1
place:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
mm_malloc:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
extend_heap:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [4096:f] pred: [(nil)] succ: [(nil)] footer: [4096:f]
0xf6154020: EOL
CNT: 2
place:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
mm_malloc:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
extend_heap:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [4096:f] pred: [(nil)] succ: [(nil)] footer: [4096:f]
0xf6154020: EOL
CNT: 3
place:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
mm_malloc:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
extend_heap:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [4096:f] pred: [(nil)] succ: [(nil)] footer: [4096:f]
0xf6154020: EOL
(...)
CNT: 12
place:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
mm_malloc:
Heap (0xf6153018):
0xf6153018: header: [8:a] footer: [8:a]
0xf6153020: header: [24:a] footer: [24:a]
0xf6153038: header: [4072:f] pred: [(nil)] succ: [(nil)] footer: [4072:f]
0xf6154020: EOL
这是我的源代码(mm.c)的样子:
/*
* Simple, 32-bit and 64-bit clean allocator based on explicit free
* lists, first-fit placement, and boundary tag coalescing, as described
* in the CS:APP3e text. Blocks must be aligned to doubleword (8 byte)
* boundaries. Minimum block size is 16 bytes. Insertion policy is LIFO.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mm.h"
#include "memlib.h"
team_t team = {
"A",
"B",
"C",
"",
""
};
/* Macros for heapchecker */
#define DEBUG
#define CHECKHEAP printf("%s%c\n", __func__, ':'); checkheap(1);
/* $begin mallocmacros */
/* Basic constants and macros */
#define WSIZE 4 /* Word and header/footer size (bytes) */ //line:vm:mm:beginconst
#define DSIZE 8 /* Double word size (bytes) */
#define CHUNKSIZE (1<<12) /* Extend heap by this amount (bytes) */ //line:vm:mm:endconst
#define MAX(x, y) ((x) > (y)? (x) : (y))
/* Pack a size and allocated bit into a word */
#define PACK(size, alloc) ((size) | (alloc)) //line:vm:mm:pack
/* Read and write a word at address p */
#define GET(p) (*(unsigned int *)(p)) //line:vm:mm:get
#define PUT(p, val) (*(unsigned int *)(p) = (val)) //line:vm:mm:put
/* Read the size and allocated fields from address p */
#define GET_SIZE(p) (GET(p) & ~0x7) //line:vm:mm:getsize
#define GET_ALLOC(p) (GET(p) & 0x1) //line:vm:mm:getalloc
/* Given block ptr bp, compute address of its header and footer */
#define HDRP(bp) ((char *)(bp) - WSIZE) //line:vm:mm:hdrp
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) //line:vm:mm:ftrp
/* Given block ptr bp, compute address of next and previous blocks */
#define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE))) //line:vm:mm:nextblkp
#define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE))) //line:vm:mm:prevblkp
/* Given block ptr bp, return next square's address */
#define NEXT_SQR(bp) ((char*)(bp) + WSIZE)
#define MIN_BLOCK_SIZE 3*DSIZE
/* $end mallocmacros */
/* Global variables */
static char *heap_listp = 0; /* Pointer to first block */
static char *free_ptr = 0; /* Pointer to last accessed(LIFO) empty block */
int cnt = 0;
/* Function prototypes for internal helper routines */
static void *extend_heap(size_t words);
static void place(void *bp, size_t asize);
static void *find_fit(size_t asize);
static void *coalesce(void *bp);
static void printblock(void *bp);
static void checkheap(int verbose);
static void checkblock(void *bp);
/*
* mm_init - Initialize the memory manager
*/
/* $begin mminit */
int mm_init(void)
{
mem_deinit();
mem_init();
heap_listp = NULL;
free_ptr = NULL;
/* Create the initial empty heap */
if ((heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1) //line:vm:mm:begininit
return -1;
PUT(heap_listp, 0); /* Alignment padding */
PUT(heap_listp + (1*WSIZE), PACK(DSIZE, 1)); /* Prologue header */
PUT(heap_listp + (2*WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
PUT(heap_listp + (3*WSIZE), PACK(0, 1)); /* Epilogue header */
heap_listp += (2*WSIZE); //line:vm:mm:endinit
/* Extend the empty heap with a free block of CHUNKSIZE bytes */
if (extend_heap(CHUNKSIZE/WSIZE) == NULL) {
return -1;
}
return 0;
}
/* $end mminit */
/*
* mm_malloc - Allocate a block with at least size bytes of payload
*/
/* $begin mmmalloc */
void *mm_malloc(size_t size)
{
#ifdef DEBUG
cnt++;
printf("CNT: %d\n", cnt);
#endif
size_t asize; /* Adjusted block size */
size_t extendsize; /* Amount to extend heap if no fit */
char *bp;
if (heap_listp == NULL){
mm_init();
}
/* Ignore spurious requests */
if (size == 0)
return NULL;
/* Adjust block size to include overhead and alignment reqs. */
if (size <= MIN_BLOCK_SIZE - DSIZE)
asize = MIN_BLOCK_SIZE;
else
asize = DSIZE * ( (size + (MIN_BLOCK_SIZE - DSIZE) + (DSIZE-1)) / DSIZE);
/* Search the free list for a fit */
if ((bp = find_fit(asize)) != NULL) {
place(bp, asize);
#ifdef DEBUG
CHECKHEAP
#endif
return bp;
}
/* No fit found. Get more memory and place the block */
extendsize = MAX(asize,CHUNKSIZE);
if ((bp = extend_heap(extendsize/WSIZE)) == NULL)
return NULL;
place(bp, asize);
#ifdef DEBUG
CHECKHEAP
#endif
return bp;
}
/* $end mmmalloc */
/*
* mm_free - Free a block
*/
/* $begin mmfree */
void mm_free(void *bp)
{
if (bp == 0)
return;
size_t size = GET_SIZE(HDRP(bp));
if (heap_listp == 0){
mm_init();
}
PUT(HDRP(bp), PACK(size, 0));
PUT(FTRP(bp), PACK(size, 0));
PUT(bp, NULL); /* ‘pred’ pointer of this block is NULL pointer */
PUT(NEXT_SQR(bp), free_ptr); /* ‘succ’ pointer of this block is previous ‘top’ of stack */
if(free_ptr != NULL)
PUT(free_ptr, bp); /* ‘prev’ pointer of previous ‘top’ of stack is this new bp. */
free_ptr = bp;
coalesce(bp);
#ifdef DEBUG
CHECKHEAP
#endif
}
/*
* coalesce - Boundary tag coalescing. Return ptr to coalesced block
*/
static void *coalesce(void *bp)
{
/* We assume that coalesce(bp) has been called following extend_heap or mm_free.
* Therefore, the block pointed to by bp is also pointed to by free_ptr; it is the top of stack.
* In Cases 2-4, there is another allocated block besides bp(top). This means that bp's succ pointer would
* not be NULL, other blocks' pred pointers would not be NULL. Of course, bp's pred pointer would be NULL,
* and we cannot guarantee any conditions about other blocks' succ pointers.
*/
size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
size_t size = GET_SIZE(HDRP(bp));
if (prev_alloc && next_alloc) { /* Case 1 */
return bp;
}
else if (prev_alloc && !next_alloc) { /* Case 2 */
void* a = bp;
void* a1 = GET(a); void* a2 = GET(NEXT_SQR(a)); /* The 'this' block, and its pointers */
void* b = NEXT_BLKP(bp);
void* b1 = GET(b); void* b2 = GET(NEXT_SQR(b)); /* The next block, and its pointers */
/* a1 is NULL, a2 is not NULL, b1 is not NULL, b2 may or may not be NULL */
if(b == a2) { /* b, the next block, is 2nd top */
/* Unified block */
size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
PUT(HDRP(bp), PACK(size, 0));
PUT(FTRP(bp), PACK(size, 0));
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), b2); /* Succ pointer of top */
/* Block at b2, if it exists */
if(b2 != NULL) {
PUT(b2, free_ptr);
}
}
else {
size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
PUT(HDRP(bp), PACK(size, 0));
PUT(FTRP(bp), PACK(size, 0));
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), a2); /* Succ pointer of top */
/* Block at a2 */
PUT(a2, free_ptr);
/* Block at b1 */
PUT(NEXT_SQR(b1), b2);
/* Block at b2, if it exists */
if(b2 != NULL) {
PUT(b2, b1);
}
}
}
else if (!prev_alloc && next_alloc) { /* Case 3 */
void* a = PREV_BLKP(bp);
void* a1 = GET(a); void* a2 = GET(NEXT_SQR(a)); /* The previous block, and its pointers */
void* b = bp;
void* b1 = GET(b); void* b2 = GET(NEXT_SQR(b)); /* The 'this' block, and its pointers */
/* b1 is NULL, b2 is not NULL, a1 is not NULL, a2 may or may not be NULL */
if(a == b2) { /* a, the previous block, is 2nd top */
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp)));
PUT(FTRP(bp), PACK(size, 0));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), a2); /* Succ pointer of top */
/* Block at a2, if it exists */
if(a2 != NULL) {
PUT(a2, free_ptr);
}
}
else {
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp)));
PUT(FTRP(bp), PACK(size, 0));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), b2); /* Succ pointer of top */
/* Block at b2 */
PUT(b2, free_ptr);
/* Block at a1 */
PUT(NEXT_SQR(a1), a2);
/* Block at a2, if it exists */
if(a2 != NULL) {
PUT(a2, a1);
}
}
}
else { /* Case 4 */
void* a = PREV_BLKP(bp);
void* a1 = GET(a); void* a2 = GET(NEXT_SQR(a)); /* The previous block, and its pointers */
void* b = bp;
void* b1 = GET(b); void* b2 = GET(NEXT_SQR(b)); /* The 'this' block, and its pointers */
void* c = NEXT_BLKP(bp);
void* c1 = GET(b); void* c2 = GET(NEXT_SQR(c)); /* The next block, and its pointers */
/* a1 is not NULL, a2 may or may not be NULL,
* b1 is NULL, b2 is not NULL,
* c1 is not NULL, c2 may or may not be NULL */
if(b2 == a) { /* a is second top */
if(a2 == c) { /* c is third top */
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), c2); /* Succ pointer of top */
/* Block at b2(=a), a1(=b), a2(=c), c1(=a) are all unified block */
/* Block at c2, if it exists */
if(c2 != NULL) {
PUT(c2, free_ptr);
}
}
else {
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), a2); /* Succ pointer of top */
/* Block at b2(=a), a1(=b) are unified block */
/* Block at a2. It exists */
PUT(a2, free_ptr);
/* Block at c1. It exists */
PUT(NEXT_SQR(c1), c2);
/* Block at c2, if it exists */
if(c2 != NULL) {
PUT(c2, c1);
}
}
}
else if (b2 == c) { /* c is second top */
if(c2 == a) { /* a is third top */
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), a2); /* Succ pointer of top */
/* Block at b2(=c), c1(=b), c2(=a), a1(=c) are all unified block */
/* Block at a2, if it exists */
if(a2 != NULL) {
PUT(a2, free_ptr);
}
}
else {
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), c2); /* Succ pointer of top */
/* Block at b2, c1 are unified block */
/* Block at c2. It exists */
PUT(c2, free_ptr);
/* Block at a1. It exists */
PUT(NEXT_SQR(a1), a2);
/* Block at a2, if it exists */
if(a2 != NULL) {
PUT(a2, a1);
}
}
}
else {
/* Unified block */
size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
bp = PREV_BLKP(bp);
free_ptr = bp; /* Re-establish top of stack */
PUT(bp, NULL); /* Pred pointer of top */
PUT(NEXT_SQR(bp), b2); /* Succ pointer of top */
if(a2 == c) {
/* Block at a2(=c), c1(=a) are unified block */
/* Block at b2 */
PUT(b2, free_ptr);
/* Block at c2, If it exists */
if(c2 != NULL) {
PUT(c2, a1);
}
/* Block at a1 */
PUT(NEXT_SQR(a1), c2);
}
else if(c2 == a) {
/* Block at c2(=a), a1(=c) are unified block */
/* Block at b2 */
PUT(b2, free_ptr);
/* Block at c1 */
PUT(NEXT_SQR(c1), a2);
/* Block at a2, If it exists */
if(a2 != NULL) {
PUT(a2, c1);
}
}
else {
/* Block at b2 */
PUT(b2, free_ptr);
/* Block at a1 */
PUT(NEXT_SQR(a1), a2);
/* Block at a2, if it exists */
if(a2 != NULL) {
PUT(a2, a1);
}
/* Block at c1 */
PUT(NEXT_SQR(c1), c2);
/* Block at c2, if it exists */
if(c2 != NULL) {
PUT(c2, c1);
}
}
}
}
#ifdef DEBUGG
CHECKHEAP
#endif
return bp;
}
/* $end mmfree */
/*
* mm_realloc
* This function is never called for trace files I used.
*/
void *mm_realloc(void *ptr, size_t size)
{
return NULL;
}
/*
* mm_checkheap - Check the heap for correctness
*/
void mm_checkheap(int verbose)
{
checkheap(verbose);
}
/*
* The remaining routines are internal helper routines
*/
/*
* extend_heap - Extend heap with free block and return its block pointer
*/
/* $begin mmextendheap */
static void *extend_heap(size_t words)
{
char *bp;
size_t size;
/* Allocate an even number of words to maintain alignment */
size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; //line:vm:mm:beginextend
if ((long)(bp = mem_sbrk(size)) == -1)
return NULL; //line:vm:mm:endextend
/* Initialize free block header/footer and the epilogue header */
PUT(HDRP(bp), PACK(size, 0)); /* Free block header */ //line:vm:mm:freeblockhdr
PUT(FTRP(bp), PACK(size, 0)); /* Free block footer */ //line:vm:mm:freeblockftr
PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ //line:vm:mm:newepihdr
PUT(bp, NULL); /* ‘pred’ pointer of this block is NULL pointer */
PUT(NEXT_SQR(bp), free_ptr); /* ‘succ’ pointer of this block is previous ‘top’ of stack */
if(free_ptr != NULL)
PUT(free_ptr, bp); /* ‘prev’ pointer of previous ‘top’ of stack is this new bp. */
free_ptr = bp;
/* Coalesce if the previous block was free */
void* p = coalesce(bp);
#ifdef DEBUG
CHECKHEAP
#endif
return p; //line:vm:mm:returnblock
}
/* $end mmextendheap */
/*
* place - Place block of asize bytes at start of free block bp
* and split if remainder would be at least minimum block size
*/
static void place(void *bp, size_t asize)
{
size_t csize = GET_SIZE(HDRP(bp));
int use_all_space = ( (csize - asize) < (MIN_BLOCK_SIZE) );
/* 0 if it splits and makes small free block, 1 if it uses all space */
int write_to_top = ( bp == free_ptr );
/* 0 if we’re not writing to top, 1 if we are */
//printf("%d\t %d\n", use_all_space, write_to_top);
char* alpha = NULL;
char* gamma = NULL;
if( use_all_space && write_to_top) /* Case 1 */ {
alpha = GET(NEXT_SQR(bp)); /* Pointer to next free block in “Stack” */
if(alpha != NULL)
PUT(alpha, NULL); /* Change pred of alpha to “NULL” */
free_ptr = alpha; /* Change top of “Stack” */
/* Allocate space */
PUT(HDRP(bp), PACK(csize, 1));
PUT(FTRP(bp), PACK(csize, 1));
}
else if (!use_all_space && write_to_top) /* Case 2 */ {
/* Get pointer to next free block within LIFO stack */
alpha = GET(NEXT_SQR(bp));
/* Allocate space */
PUT(HDRP(bp), PACK(asize, 1));
PUT(FTRP(bp), PACK(asize, 1));
bp = NEXT_BLKP(bp);
PUT(HDRP(bp), PACK(csize - asize, 0));
PUT(FTRP(bp), PACK(csize - asize, 0)); /* bp now points to ‘new free block’ */
//printf("Pointer addresses: %p %p %p\n", bp, NEXT_SQR(bp), alpha);
PUT(bp, NULL); /* Make pred of bp “NULL” */
PUT(NEXT_SQR(bp), alpha); /* Make succ of bp “alpha” */
if(alpha != NULL)
PUT(alpha, bp); /* Change pred of alpha to “bp” */
free_ptr = bp; /* Change top of “Stack” */
}
else if( use_all_space && !write_to_top) /* Case 3 */ {
/* Get pointer to previous free block within LIFO stack */
gamma = GET(bp);
/* Get pointer to next free block within LIFO stack */
alpha = GET(NEXT_SQR(bp));
if(gamma != NULL)
PUT(NEXT_SQR(gamma), alpha); /* Change succ of gamma to “alpha” */
if(alpha != NULL)
PUT(alpha, gamma); /* Change pred of alpha to “gamma” */
/* Allocate space */
PUT(HDRP(bp), PACK(csize, 1));
PUT(FTRP(bp), PACK(csize, 1));
}
else /* Case 4 */ {
/* Get pointer to previous free block within LIFO stack */
gamma = GET(bp);
/* Get pointer to next free block within LIFO stack */
alpha = GET(NEXT_SQR(bp));
/* Allocate space */
PUT(HDRP(bp), PACK(asize, 1));
PUT(FTRP(bp), PACK(asize, 1));
bp = NEXT_BLKP(bp);
PUT(HDRP(bp), PACK(csize - asize, 0));
PUT(FTRP(bp), PACK(csize - asize, 0)); /* bp now points to ‘new free block’ */
PUT(bp, NULL); /* Make pred of bp “NULL” */
PUT(NEXT_SQR(bp), free_ptr); /* Make succ of bp “old top” */
if(free_ptr != NULL)
PUT(free_ptr, bp); /* Change prev of old top to “bp” */
free_ptr = bp; /* Change top of “Stack” */
if(gamma != NULL)
PUT(NEXT_SQR(gamma), alpha); /* Change succ of gamma to “alpha” */
if(alpha != NULL)
PUT(alpha, gamma); /* Change pred of alpha to “gamma” */
}
#ifdef DEBUG
CHECKHEAP
#endif
}
/* $end mmplace */
/*
* find_fit - Find a fit for a block with asize bytes
*/
/* $begin mmfirstfit */
/* $begin mmfirstfit-proto */
static void *find_fit(size_t asize)
/* $end mmfirstfit-proto */
{
/* $end mmfirstfit */
/* $begin mmfirstfit */
void *bp;
bp = free_ptr;
do {
if(asize <= GET_SIZE(HDRP(bp))) {
//printf("found fit ... %d\n", GET_SIZE(HDRP(bp)));
return bp;
}
else {
bp = GET(NEXT_SQR(bp));
}
} while(bp != NULL);
//printf("Yes, find_fit is returning NULL\n");
return NULL; /* No fit */
}
/* $end mmfirstfit */
static void printblock(void *bp)
{
size_t hsize, halloc, fsize, falloc;
checkheap(0);
hsize = GET_SIZE(HDRP(bp));
halloc = GET_ALLOC(HDRP(bp));
fsize = GET_SIZE(FTRP(bp));
falloc = GET_ALLOC(FTRP(bp));
if (hsize == 0) {
printf("%p: EOL\n", bp);
return;
}
if(!halloc) {
printf("%p: header: [%ld:%c] pred: [%p] succ: [%p] footer: [%ld:%c]\n", bp,
hsize, (halloc ? 'a' : 'f'),
GET(bp), GET(NEXT_SQR(bp)),
fsize, (falloc ? 'a' : 'f'));
}
else {
printf("%p: header: [%ld:%c] footer: [%ld:%c]\n", bp,
hsize, (halloc ? 'a' : 'f'),
fsize, (falloc ? 'a' : 'f'));
}
}
static void checkblock(void *bp)
{
if ((size_t)bp % 8)
printf("Error: %p is not doubleword aligned\n", bp);
if (GET(HDRP(bp)) != GET(FTRP(bp)))
printf("Error: header does not match footer\n");
}
/*
* checkheap - Minimal check of the heap for consistency
*/
void checkheap(int verbose)
{
char *bp = heap_listp;
if (verbose)
printf("Heap (%p):\n", heap_listp);
if ((GET_SIZE(HDRP(heap_listp)) != DSIZE) || !GET_ALLOC(HDRP(heap_listp)))
printf("Bad prologue header\n");
checkblock(heap_listp);
for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
if (verbose)
printblock(bp);
checkblock(bp);
}
if (verbose)
printblock(bp);
if ((GET_SIZE(HDRP(bp)) != 0) || !(GET_ALLOC(HDRP(bp))))
printf("Bad epilogue header\n");
if ((GET_SIZE(HDRP(free_ptr))) < 3*WSIZE || (size_t)free_ptr % 8) {
printf("Error: %p is not doubleword aligned\n", free_ptr);
}
}
有没有人了解或知道发生了什么,或者我该如何解决?
解决方案
推荐阅读
- python - 如何在 tkinter 中获取活动条目小部件?
- javascript - 反应原生的承诺中的条件渲染
- tsql - 创建具有更改值的副本,TSQL
- javascript - 过渡项目符号导航
- mule4 - MULE 4:批处理:批处理组件如何处理集合中的记录?
- docusignapi - DcouSign 收件箱为空
- python - Pythonic 使用排序函数的方法
- c# - Streamwriter 未将命令正确写入网络流
- python - github存储库中的json文件是否需要时间来更新?
- flutter - Dart / Flutter:使用基对象中的 fromJson 将 json 映射到具有基类的对象