【发布时间】:2011-02-12 03:51:18
【问题描述】:
有一个关于 C++ 指针添加的问题。如果您查看提供的屏幕截图,您基本上可以看到我正在执行 memcpy(m_pBuf + m_iWritePtr .... 并且此内存指针添加未按预期工作。
我曾认为添加 m_pBuf + m_iWritePtr 会将 m_iWritePtr 字节添加到我的内存地址 m_pBuf。 m_pBuf 是指向结构数组的指针;即 (T *)m_pBuf = new T[cnt] 其中 T 是类型名,cnt 是分配的 T 个对象的数量。在这种情况下,T 是一个简单的结构。本例中 sizeof(T) 为 260。
memcpy 调用出错,我知道我的指针数学错误,但我不是 100% 确定原因。我认为 memcpy 被编码为获取基地址并添加一些 n * 260 字节以获得缓冲区的偏移量。注意:当这不是模板实现并且 T 只是一个 char * 时,此代码可以正常工作。现在 T 是某个类型名的模板,偏移量添加不再按预期工作。
因此,如果您查看下面的屏幕截图,以下是我使用编译器的调试器/检查器和计算器所做的各种计算/参考的结果:
The memory address of m_pBuf = 0x01E7E0E0
The memory address of m_pBuf[1] = 0x01E8EE04
the memory address of m_pBuf+1 = 0x01E8EE04
the memory address of m_pBuf++ = 0x01E8EBFC
the memory address of m_pBuf+260 = 0x01E7E1E4 (the calculator's result)
我试图了解这里发生了什么。前两个似乎是正确的,但我不明白为什么这些都不相等。这是 Windows 7-64 位上的 32 位编译器。
为了进一步解释,这是一个 T 类型的环形缓冲区,大小为 n * T 个存储对象。代码如下:
template<typename T>
bool TMsgBuffer<T>::PutMsgEx(T *pBuf, unsigned long nObjCount )
{
bool bResult = false;
unsigned long MaxWriteSize, nPutLen;
Lock();
MaxWriteSize = GetMaxWriteSize(); // this returns size of my buffer in total.
nPutLen = nObjCount * m_nObjSize; // m_nObjSize is set else where to sizeof(T)
if(nPutLen <= MaxWriteSize)
{
// easy case, no wrapping
if( m_iWritePtr + nPutLen <= m_nBufSize )
{
memcpy(m_pBuf + m_iWritePtr, pBuf, nPutLen);
m_iWritePtr += nPutLen;
}
else // need to wrap
{
m_iFirstChunkSize = m_nBufSize - m_iWritePtr;
m_iSecondChunkSize = nPutLen - m_iFirstChunkSize;
memcpy(m_pBuf + m_iWritePtr, pBuf, m_iFirstChunkSize );
memcpy(m_pBuf, pBuf + m_iFirstChunkSize, m_iSecondChunkSize );
m_iWritePtr = m_iSecondChunkSize;
}
//m_MsgCount++;
m_MsgCount+= nObjCount;
bResult = true;
}
Unlock();
return bResult;
}
【问题讨论】: