2016-02-16 2 views
0
#include <iostream> 
#include <sstream> 
#include "blocknode.h" 

using namespace std; 

class MemoryManager 
{ 
public: 
MemoryManager(unsigned int memsize); 
unsigned char * malloc(unsigned int request); 
void free(unsigned char * blockptr); 
blocknode *getFirstPtr(); 
friend ostream & operator<<(ostream & out,const MemoryManager &M); 

private: 
unsigned int memsize; 
unsigned char *baseptr; 
blocknode * firstBlock; 

void mergeForward(blocknode *p); 
void splitBlock(blocknode *p,unsigned int chunksize); 
}; 

Вот файл BLOCKNODE.hC функции в C++

#include <iostream> 

using namespace std; 

struct blocknode 
{ 
    unsigned int bsize; 
    bool free; 
    unsigned char *bptr; 
    blocknode *next; 
    blocknode *prev; 

    blocknode(unsigned int sz,unsigned char *b,bool f=true,blocknode 
    *p=0,blocknode *n=0): 
    bsize(sz),free(f),bptr(b),prev(p),next(n) {} 
    }; 

CPP FILE

#include <cassert> 
#include <iostream> 
#include <sstream> 
#include <string> 
#include "MemoryManager.h" 

using namespace std; 


ostream & operator<<(ostream & out,const MemoryManager &M) 
{ 
blocknode *tmp = M.firstBlock; 
assert(tmp); 
while(tmp) 
{ 
    out << "[" << tmp->bsize << ","; 
    if (tmp->free) 
out << "free] "; 
    else 
out << "allocated] "; 
    if (tmp->next) 
out << " -> "; 
    tmp = tmp->next; 
} 
return out; 
} 

MemoryManager::MemoryManager(unsigned int memtotal): memsize(memtotal) 
{ 
baseptr = new unsigned char[memsize]; 
firstBlock = new blocknode(memsize,baseptr); 
} 

blocknode *MemoryManager::getFirstPtr() 
{ 
return firstBlock; 
} 

unsigned char * MemoryManager::malloc(unsigned int request) 
// Finds the first block in the list whose size is >= request 
// If the block's size is strictly greater than request 
// the block is split, with the newly create block being free. 
// It then changes the original block's free status to false 
{ 
blocknode * tmp = this->firstBlock; 
assert(tmp); 
while (tmp){ 
    if (tmp->bsize >= request){ 
     if (tmp->bsize > request){ 
      splitBlock(tmp, request); 
      return tmp->bptr; 
     } 
     tmp->free = false; 
     return tmp->bptr; 

    } 
    tmp = tmp->next; 
} 

} 

void MemoryManager::splitBlock(blocknode *p, unsigned int chunksize) 
// Utility function. Inserts a block after that represented by p 
// changing p's blocksize to chunksize; the new successor node 
// will have blocksize the original blocksize of p minus chunksize and 
// will represent a free block. 
// Preconditions: p represents a free block with block size > chunksize 
// and the modified target of p will still be free. 

{ 
if (p->free == false || p->bsize <= chunksize) { 
    cout << "Error splitting memory....exiting with error code 1" << endl; 
    exit(1); 
} 
blocknode * heap = new blocknode(p->bsize,p->bptr + chunksize,true,0,0); 
heap->bsize = p->bsize - chunksize; 
heap->prev = p; 
p->bsize = chunksize; 
p->next = heap; 
} 

void MemoryManager::mergeForward(blocknode *p) 
// merges two consecutive free blocks 
// using a pointer to the first blocknode; 
// following blocknode is deleted 
{ 

    blocknode * tmp = p->next; 
    p->bsize += p->next->bsize; 
    p->next = tmp->next; 
    tmp->next->prev = p; 
    delete tmp; 

} 


void MemoryManager::free(unsigned char *blockptr) 
// makes the block represented by the blocknode free 
// and merges with successor, if it is free; also 
// merges with the predecessor, it it is free 
{ 
blocknode * tmp = this->firstBlock->next; 
assert(tmp); 
while (tmp) { 
    if (tmp->bptr == blockptr) { 
     tmp->free = true; 
     if (tmp->free == true && tmp->next->free == true) { 
      mergeForward(tmp); 
     } 
     if (tmp->free == true && tmp->prev->free == true) { 
      mergeForward(tmp->prev); 
     } 
    } 
} 

}

Цель этой программы заключается в значительной степени имитировать C который имеет дело с malloc() и free(). У меня возникают проблемы с последними четырьмя функциями файла cpp менеджера памяти. (см. комментарии) Код компилируется, однако моя программа вылетает во время выполнения, в ней говорится, что в ячейке памяти есть исключение без исключения, XXXXXXXXX знает, что это вызывает? Линия 110 ("если (tmp-> next-> бесплатно == верно)"), где программа разбивает

+5

Используйте отладчик. Также см. [Как отладить небольшие программы] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – chris

+2

Запустите программу в отладчике, чтобы, по крайней мере, вы могли узнать, какая строка кода вызывает сбой. И затем продолжайте, так как ваш отладчик может сделать гораздо больше, чтобы помочь вам найти проблему самостоятельно. – kaylum

+1

Хотя это не имеет никакого отношения к предполагаемому сбою, кажется, что ваш MemoryManager :: free() имеет очевидную ошибку - он не может освободить выделенный блок, если он является первым блоком в списке. –

ответ

1

Когда MemoryManager::free() вызовы mergeForward() (первый вызов в mergeForward()) в результате того, что происходит в mergeForward(), похоже, что указатель tmp, используемый free(), больше не будет действителен, потому что mergeForward() delete d it.

Разрушение tmp, сразу же после этого приведет к неопределенному поведению.

Это в дополнение к другой ошибке в free(), которую я отметил в комментариях.

+0

nevermind мой предыдущий комментарий – Flower

+0

Я обновил бесплатную функцию, и она не сработает, однако, когда программа приступает к выполнению free(), она бесконечно петляет – Flower

+1

Я уверен, если вы тщательно объясните логику, которую использует функция free() ваша резиновая утка, ваша резиновая утка объяснит вам, что это за ошибка. Вы можете найти свою резиновую утку по адресу https://en.wikipedia.org/wiki/Rubber_duck_debugging –

Смежные вопросы