Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内存管理器-访问冲突写入位置异常_C++_Exception_Pointers_Memory Management - Fatal编程技术网

C++ 内存管理器-访问冲突写入位置异常

C++ 内存管理器-访问冲突写入位置异常,c++,exception,pointers,memory-management,C++,Exception,Pointers,Memory Management,我一直在做一些关于游戏引擎开发的研究,最后我开始尝试编写一个Memorymanager。我从Eberly的游戏引擎设计书中得到了这个想法。在构造函数中,我分配一个memoryblock,并向其添加一个页眉和页脚,这两个页眉和页脚都有一个size属性并使用。但现在我有了写作的机会。我已经听说指针是常量并且只能读取,但我不知道如何解决这个问题 以下是MemoryManager.h文件: // MemoryManager.h - Header file // #ifndef H_MemoryMana

我一直在做一些关于游戏引擎开发的研究,最后我开始尝试编写一个Memorymanager。我从Eberly的游戏引擎设计书中得到了这个想法。在构造函数中,我分配一个memoryblock,并向其添加一个页眉和页脚,这两个页眉和页脚都有一个size属性并使用。但现在我有了写作的机会。我已经听说指针是常量并且只能读取,但我不知道如何解决这个问题

以下是MemoryManager.h文件:

// MemoryManager.h - Header file //

#ifndef H_MemoryManager
#define H_MemoryManager

#include "IMemoryManager.h"

class HeaderBlock
{
public:
bool Used;
unsigned int Size;

HeaderBlock* Prev;
HeaderBlock* Next;
};

class FooterBlock
{
public:
bool Used;
unsigned int Size;
};

class MemoryManager : public IMemoryManager
{
private:
int m_MemoryBudget;
char* m_FullMemory;
HeaderBlock* m_FreeBlock;

int m_hsize;        // Size of the header
int m_fsize;        // Size of the footer
int m_hfsize;       // Size of the HeaderandFooter

public:
// Constructor and Destructor
MemoryManager(int Budget);
virtual ~MemoryManager();

// Functions
virtual char* Allocate(unsigned int RequestSize);
virtual char* Deallocate(char* pDeallocate);

HeaderBlock* SearchByPolicy(unsigned int RequestSize);
 };

#endif
以下是构造函数实现:

MemoryManager::MemoryManager(int Budget)
{
m_MemoryBudget = Budget;
m_FullMemory = (char*)malloc(m_MemoryBudget);

m_hsize = sizeof(HeaderBlock);
m_fsize = sizeof(FooterBlock);
m_hfsize = m_hsize + m_fsize;

HeaderBlock* header = (HeaderBlock*)m_FullMemory;
header->Used = false;
header->Size = m_MemoryBudget;

FooterBlock* footer = (FooterBlock*)(m_FullMemory + m_MemoryBudget - m_fsize);
footer->Used = false;
footer->Size = m_MemoryBudget;

header->Prev = header;
header->Next = header;

m_FreeBlock = (HeaderBlock*)m_FullMemory;
}
这是一种分配方法,我在错误处得到错误

usedHeader->Used = true;
usedFooter->Used = true;
freeHeader->Used = false; 
freeFooter->Used = false; // HERE I GET THE EXCEPTION

我已经检查了SearchByPolicy函数是否返回有效指针,如果它能找到比请求更大的内存块,它确实会返回有效指针


我希望你能帮助我

您的问题是指针算法:

FooterBlock* footer = (FooterBlock*)((header + Size - m_fsize));
意味着

您很可能想要:

uint_ptr ofs = (uint_ptr)header;
FooterBlock* footer = (FooterBlock*)((ofs + Size - m_fsize));
您可以在
stdint.h
中找到
uint\u ptr
,或在
windows.h


更新:

根据评论中的问题

IMemoryManager* memorymanager = new MemoryManager(1000000); 
Logger* logger = (Logger*)memorymanager->Allocate(sizeof(Logger)); 
logger->WriteToBuffer(log, "HOI");
这将失败,因为不会调用
记录器
的构造函数,有几种方法可以解决此问题:

  • 调用一个构造方法,虽然不是很好
  • 使用新位置:
(不幸的是,列出了中断代码格式,因此我必须在此处插入此项…)

  • 在全局范围内重载
    ::new
    ::delete
    运算符(非常糟糕)
  • 创建一个可继承对象以重载
    新建
    删除
这要求内存管理器在该点可用(或作为参数传递):


非常感谢,它就像一个符咒~!还有一个问题:假设我有一个指向内存管理器的指针和一个记录器:IMemoryManager*memorymanager=newmemorymanager(1000000);Logger*Logger=(Logger*)内存管理器>分配(sizeof(Logger));记录器->写入缓冲区(日志,“HOI”);那么这有什么问题?再次非常感谢,如果你能回答最后一个问题,我不会再问你任何问题:P你得到我的投票@ChristianVeenman:您正在分配一个对象而没有初始化它(不会调用构造函数)。请看我的更新问题。好的,非常感谢!你真的很擅长解释!您认为创建一个构造函数并在构造函数中使用placement new在分配的内存中初始化它是一个好主意吗?顺便说一句,我接受了你的回答@ChristianVeenman:我不知道你的意思是什么,
Logger
的构造函数在没有放置new的情况下是不会被调用的,在这种情况下,这并不重要,因为你可以在构造函数中做任何事情
uint_ptr ofs = (uint_ptr)header;
FooterBlock* footer = (FooterBlock*)((ofs + Size - m_fsize));
IMemoryManager* memorymanager = new MemoryManager(1000000); 
Logger* logger = (Logger*)memorymanager->Allocate(sizeof(Logger)); 
logger->WriteToBuffer(log, "HOI");
IMemoryManager* memorymanager = new MemoryManager(1000000); 
Logger* logger = new (memorymanager->Allocate(sizeof(Logger))) (); 
logger->WriteToBuffer(log, "HOI");
class PoolObject
{
    void* operator new (std::size_t n)
    {
        return memorymanager->Allocate(n);
    }

    void operator delete (void* p)
    {
        memorymanager->Free(p);
    }
}

class Logger : PoolObject
{
}

Logger* logger = new Logger();