题
我试图建立一个非常简约的存储器读图书馆阅读一些unsigned int
s出来。然而,我碰上当ReadUnsignedInt
方法要返回一个“堆损坏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;
}
解决方案
迈克尔和纳文兼得发现在你的代码相同的主要缺陷,但不是唯一的瑕疵。
shared_ptr
将delete
被指向在对象时其引用计数变为零。
这意味着你只能给它通过物体分配new
- 不new[]
您可能希望使用shared_ptr<vector<byte> >
或 boost::shared_array<byte>
一>代替。
其他提示
的问题是:
new byte(numberOfBytes)
此分配具有numberOfBytes的值的单个字节。
您想要做的:
new byte[numberOfBytes]
哪些分配字节numberOfBytes阵列长。
但既然你知道你只是读取4个字节,何苦在所有分配的内存?只是通过一个无符号整型的地址压入堆栈。
你的代码的基本问题已经指出了。看着它,我在想为什么你会在这里都使用一个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);
等。
如果你担心返回字符的载体的效率低下,你可能不应该 - VC ++(像其他大多数较新的编译器)有什么叫做“命名返回值优化”,这意味着在一个情况这样,它通过一个隐藏的参考分配结果的向量,并会的ReadBytes用它来存放数据直接到哪里去无论如何收场。对于这个问题,有任何合理的优化开启所有,的ReadBytes几乎肯定会最终成为内联函数,所以没有什么真正参与被“通过”或“返回”可言。
在另一方面,该代码将不会与旧的编译工作特别好 - 与旧足够的编译器,使用成员模板函数的版本甚至可能不会编译。只要您使用的是较新的编译器,但是,生活应该是不错的。
相信new byte(numberOfBytes)
应当new byte[numberOfBytes]
。否则,你会只分配了一个字节。刚刚完成了答案,因为@ephemient表明您不能使用的shared_ptr在这里,因为它会做一个delete
这里,你应该做的delete[]
。如果不这样做,该行为将是不确定的。