我试图构建一个非常简约的内存读取库来读取其中的一些unsigned int。但是,当ReadUnsignedInt方法想返回时,我会遇到一条“检测到的堆损坏”错误消息。
检测到
堆损坏。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;
}发布于 2009-10-14 16:51:22
Michael和Naveen都在代码中发现了相同的主要缺陷,但并不是唯一的缺陷。
当指向对象的引用计数为零时,shared_ptr将对其进行delete。
这意味着您只能给它分配由new分配的对象--而不是new[]。
您可能希望使用shared_ptr<vector<byte> >或boost::shared_array。
发布于 2009-10-14 16:50:08
问题是:
new byte(numberOfBytes)这将分配一个值为numberOfBytes的单个字节。
你想做的是:
new byte[numberOfBytes] 它分配一个字节数组numberOfBytes long。
但是既然你知道你只读了4个字节,为什么还要去分配内存呢?只需在堆栈上传递未签名int的地址即可。
发布于 2009-10-14 17:48:02
您的代码的基本问题已经指出了。看看它,我想知道为什么您会在这里使用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几乎肯定会成为内联函数,因此所涉及的任何内容都不会真正得到“传递”或“返回”。
另一方面,这段代码在较旧的编译器中不能很好地工作--对于足够老的编译器,使用成员模板函数的版本可能甚至无法编译。然而,只要你使用一个合理的当前编译器,生活就应该是美好的。
https://stackoverflow.com/questions/1567557
复制相似问题