我试图建立一个非常简约的内存读取库来读取它的一些unsigned int
。但是,当ReadUnsignedInt
方法想要返回时,我遇到了“HEAP CORRUPTION DETECTED”错误消息。
HEAP CORRUPTION DETECTED。 CRT检测到应用程序在缓冲区结束后写入内存。
正如我所读到的,这可能是尝试双重删除某些内容时的原因。这可能是由std::tr1::shared_ptr
的一些错误使用引起的,但我无法确定我对它们做错了什么。代码如下(省略错误处理):
unsigned int Memory::ReadUnsignedInt (unsigned int address) const {
std::tr1::shared_ptr<byte> bytes =
this->ReadBytes(address, sizeof(unsigned int));
return *((int*)bytes.get());
// correct value (how to improve this ugly piece of code?)
}
std::tr1::shared_ptr<byte> Memory::ReadBytes (
unsigned int address, int numberOfBytes) const
{
std::tr1::shared_ptr<byte> pBuffer(new byte(numberOfBytes));
ReadProcessMemory(m_hProcess.get(), (LPCVOID)address,
pBuffer.get(), numberOfBytes * sizeof(byte), NULL))
return pBuffer;
}
答案 0 :(得分:4)
shared_ptr
将delete
指向对象。
这意味着您只能为new
分配的对象提供 - 而不是new[]
。
您可能希望改为使用shared_ptr<vector<byte> >
或boost::shared_array<byte>
。
答案 1 :(得分:2)
问题是:
new byte(numberOfBytes)
这将分配一个值为numberOfBytes的单个字节。
你想这样做:
new byte[numberOfBytes]
分配一个字节数组numberOfBytes long。
但是既然你知道你只读了4个字节,为什么还要分配内存呢?只需传递堆栈中unsigned int的地址即可。
答案 2 :(得分:2)
已经指出了代码的基本问题。看着它,我想知道你为什么要在这里使用shared_ptr。如果我这样做,我可能会使用这样的东西:
unsigned Memory::ReadUnsignedInt(unsigned address) {
unsigned ret;
ReadProcessMemory(m_hProcess.get(), (void *)address, &ret, sizeof(ret), NULL);
return ret;
}
std::vector<char> Memory::ReadBytes(unsigned address, int num) {
std::vector<char> ret(num);
ReadProcessMemory(m_hProcess.get(), (void *)address, &ret[0], num, NULL);
return ret;
}
然后再次使用模板而不是ReadUnsignedInt:
template <class T>
T Memory::Read(unsigned address) {
T ret;
ReadProcessMemory(m_hProcess.get(), (void*)address, &ret, sizeof(ret), NULL);
return ret;
}
由于您没有传递可以推导出模板参数类型的参数,因此您必须明确指定:
int x = Read<int>(wherever);
char a = Read<char>(wherever);
另一种方法是将目的地作为参数传递:
template <class T>
Memory::Read(unsigned address, T &t) {
ReadProcessMemory(my_hProcess.get(), (void *)address, &t, sizeof(t), NULL);
};
你可以使用:
Read(wherever, some_int);
Read(somewhere, some_long);
等等。
如果你担心返回char向量的效率低下,你可能不应该 - VC ++(像大多数其他合理的当前编译器一样)具有所谓的“命名返回值优化”,这意味着在某种情况下像这样,它会将一个隐藏的引用传递给你分配结果的向量,而ReadBytes将使用它直接将数据存放到最终结束的位置。就此而言,在任何合理的优化开启的情况下,ReadBytes几乎肯定会最终成为一个内联函数,所以任何涉及的东西都不会被“传递”或“返回”。
另一方面,对于较旧的编译器,此代码将无法正常工作 - 并且使用足够多的编译器,使用成员模板函数的版本可能甚至无法编译。但是,只要您使用合理的当前编译器,生活就应该很好。
答案 3 :(得分:0)
我相信new byte(numberOfBytes)
应为new byte[numberOfBytes]
。否则你只会分配一个字节。只是为了完成答案,因为@ephemient表示你不能在这里使用shared_ptr,因为它会delete
执行delete[]
。如果不这样做,行为将是未定义的。