В чем причина этой ошибки? Я создаю персональную версию malloc и бесплатную для своего класса C, но столкнулся со следующей проблемой: я разделил свободное место на 2 узла, используя метод наилучшего соответствия, чтобы вставить значение в свой связанный список, однако он возвращает неверное значение программа тестирования. Значение currentBlock + sizeof (struct Block) равно 6299672, но когда я распечатываю его из программы тестирования, он печатает 6300251. Это приводит к ошибке сегмента из-за неверного указателя, когда я освобождаю его позже в программе. Это проблема неправильного приведения или я что-то упустил?
Спасибо! Соответствующие разделы моего кода ниже:
Ниже приведены методы my_malloc и my_free:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
struct Block {
int occ; // whether block is occupied
int size; // size of block (including header)
struct Block *prev; // pointer to previous block
struct Block *next; // pointer to next block
};
static struct Block *head = NULL; // head of list
void *my_malloc(int size)
{
struct Block *currentBlock = head;
struct Block *bestFitBlock = NULL;
int bestFit = 0;
void *offset = sbrk(0);
void *ending = offset + size + sizeof(struct Block);
int success = brk(ending);
struct Block *newBlock = offset;
newBlock -> occ = 1;
newBlock -> size = size + sizeof(struct Block);
while(head != NULL && currentBlock != NULL){
//If the block you're currently looking at is free and either the same or larger size than the incoming block,
//then split the block and take up the block and have a free block
if(currentBlock -> occ == 0){
if(currentBlock -> size >= newBlock -> size){
//If the incoming block and the free block are the same size, just fill it in
if(currentBlock -> size == newBlock -> size){
currentBlock -> occ = 1;
int removeExtra = 0 - newBlock -> size;
sbrk(removeExtra);
return currentBlock + sizeof(struct Block);
}
//If they're bigger sizes, split it into 2 blocks and fill 1 in. Must also leave room for another block to the right
else if(currentBlock -> size >= newBlock -> size + sizeof(struct Block)){
//Set the integer to 1 to denote that there is a place for it to go if no blocks match size
bestFit = 1;
//Save the block in which it would fit best if no blocks match size
if(bestFitBlock == NULL){
bestFitBlock = currentBlock;
}
else if(currentBlock -> size > bestFitBlock -> size){
bestFitBlock = currentBlock;
}
}
}
}
//Go to the next block
currentBlock = currentBlock -> next;
}
//Split the block into a taken and free slot
if(bestFit == 1){
currentBlock = bestFitBlock;
int freeSize = currentBlock -> size - newBlock -> size;
currentBlock -> occ = 1;
currentBlock -> size = newBlock -> size;
void *tempPointer = (int)currentBlock + (int)currentBlock -> size;
struct Block *newFreeBlock = tempPointer;
newFreeBlock -> occ = 0;
newFreeBlock -> size = freeSize;
newFreeBlock -> next = currentBlock -> next;
newFreeBlock -> prev = currentBlock;
newFreeBlock -> next -> prev = newFreeBlock;
currentBlock -> next = newFreeBlock;
//TROUBLESHOOTING: PRINT WHAT IS SUPPOSED TO BE RETURNED
printf("%d ", (int)currentBlock + (int)sizeof(struct Block));
int removeExtra = 0 - newBlock -> size;
sbrk(removeExtra);
return (int)currentBlock + (int)sizeof(struct Block);
}
if(head == NULL){
head = newBlock;
}
else{
currentBlock = head;
while(currentBlock -> next != NULL){
currentBlock = currentBlock -> next;
}
currentBlock -> next = newBlock;
newBlock -> prev = currentBlock;
}
if(success == 0){
return offset + sizeof(struct Block);
}
else{
printf("Error - Malloc not completed\n");
return (int *)-1;
}
}
void my_free(void *data)
{
struct Block *currentBlock = head;
void *lookingFor = data - sizeof(struct Block);
while(lookingFor != currentBlock){
currentBlock = currentBlock -> next;
}
currentBlock -> occ = 0;
//If the block after the one being freed is empty, coalesce these two together
if(currentBlock -> next != NULL && currentBlock -> next -> occ == 0){
currentBlock -> size = currentBlock -> size + currentBlock -> next -> size;
currentBlock -> next = currentBlock -> next -> next;
if(currentBlock -> next != NULL){
struct Block *tempBlock = currentBlock -> next;
tempBlock -> prev = currentBlock;
}
}
//If the block before the one being freed is empty, change the current block to the previous one
//and do the same procedure as above to coalesce the two together
if(currentBlock != head && currentBlock -> prev -> occ == 0){
currentBlock = currentBlock -> prev;
currentBlock -> size = currentBlock -> size + currentBlock -> next -> size;
currentBlock -> next = currentBlock -> next -> next;
if(currentBlock -> next != NULL){
currentBlock -> next -> prev = currentBlock;
}
}
//If the free block is next to the end of the heap, decrease the size of the heap
//by disbanding the last block
if(currentBlock -> next == NULL){
int sizeDecrease = 0 - currentBlock -> size;
sbrk(sizeDecrease);
if(currentBlock == head){
brk(head);
head = NULL;
}
else{
currentBlock -> prev -> next == NULL;
}
}
}
и моя программа тестирования:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
void *my_malloc(int size);
void my_free(void *data);
//include your code
//replace malloc here with the appropriate version of my_malloc
#define MALLOC my_malloc
//replace free here with the appropriate version of my_free
#define FREE my_free
//define DUMP_HEAP() to be dump_heap() when you are done
#define DUMP_HEAP()
int main()
{
char *dummy = MALLOC(23 + 24 * 5);
FREE(dummy);
DUMP_HEAP();
char *this = MALLOC(5);
char *is = MALLOC(3);
char *a = MALLOC(2);
char *test = MALLOC(5);
char *program = MALLOC(8);
DUMP_HEAP();
strcpy(this, "this");
strcpy(is, "is");
strcpy(a, "a");
strcpy(test, "test");
strcpy(program, "program");
printf("%s %s %s %s %s\n", this, is, a, test, program);
DUMP_HEAP();
FREE(is);
FREE(test);
printf("%s %s %s %s %s\n", this, "*", a, "*", program);
DUMP_HEAP();
FREE(this);
printf("%s %s %s %s %s\n", "*", "*", a, "*", program);
DUMP_HEAP();
this = MALLOC(5);
//TROUBLESHOOTING: PRINT WHAT'S ACTUALLY BEING RETURNED
printf("%d ", (char *)this);
strcpy(this, "this");
printf("%s %s %s %s %s\n", this, "*", a, "*", program);
DUMP_HEAP();
is = MALLOC(3);
test = MALLOC(5);
//MORE TROUBLESHOOTING
printf("%d ", (char *)test);
strcpy(is, "is");
strcpy(test, "test");
printf("%s %s %s %s %s\n", this, is, a, test, program);
DUMP_HEAP();
FREE(test);
FREE(is);
FREE(a);
FREE(this);
FREE(program);
printf("%s %s %s %s %s\n", "*", "*", "*", "*", "*");
DUMP_HEAP();
return 0;
}
Проблема, с которой я столкнулся, связана с ошибкой сегмента, когда строка FREE (this) запускается в конце программы. Я предполагаю, что это из-за неправильного указателя, возвращаемого из моей функции my_malloc. Я прошу прощения за то, что код не является очень кратким, заранее спасибо за любую помощь!