【发布时间】:2011-05-12 21:40:08
【问题描述】:
我已经为循环缓冲区编写了一个模板类:
template <class T> class CRingBuffer { /* ... */ };
该类执行的某些操作依赖于对T 大小的准确评估。当T 是BYTE(即sizeof(T) == 1,检查)时,这似乎可以正常工作。但是,当我尝试使用T 是DWORD 的同一个类时,由于某种原因,sizeof(T) 的计算结果为 16。我上次检查时,双字是 4 个字节,而不是 16。有谁知道为什么这正在发生吗?谢谢。
附加信息
由于其专有性质,我无法发布所有代码,但这里是有问题的类声明和函数定义:
template <class T> class CRingBuffer
{
#pragma pack( push , 1 ) // align on a 1-byte boundary
typedef struct BUFFER_FLAGS_tag
{
T * pHead; // Points to next buffer location to write
T * pTail; // Points to next buffer location to read
BOOL blFull; // Indicates whether buffer is full.
BOOL blEmpty; // Indicates whether buffer is empty.
BOOL blOverrun; // Indicates buffer overrun.
BOOL blUnderrun; // Indicates buffer underrun.
DWORD dwItemCount; // Buffer item count.
} BUFFER_FLAGS, *LPBUFFER_FLAGS;
#pragma pack( pop ) // end 1-byte boundary alignment
// Private member variable declarations
private:
T * m_pBuffer; // Buffer location in system memory
T * m_pStart; // Buffer start location in system memory
T * m_pEnd; // Buffer end location in system memory
BUFFER_FLAGS m_tFlags; // Buffer flags.
DWORD m_dwCapacity; // The buffer capacity.
// CRingBuffer
public:
CRingBuffer( DWORD items = DEFAULT_BUF_SIZE );
~CRingBuffer();
// Public member function declarations
public:
DWORD Add( T * pItems, DWORD num = 1, LPDWORD pAdded = NULL );
DWORD Peek( T * pBuf, DWORD num = -1, DWORD offset = 0, LPDWORD pWritten = NULL );
DWORD Delete( DWORD num, LPDWORD pDeleted = NULL );
DWORD Remove( T * pBuf, DWORD num = 1, LPDWORD pRemoved = NULL );
void Flush( void );
DWORD GetItemCount( void );
BYTE GetErrorStatus( void );
// Private member function declarations
private:
void IncrementHead( LPBUFFER_FLAGS pFlags = NULL );
void IncrementTail( LPBUFFER_FLAGS pFlags = NULL );
};
template <class T> void CRingBuffer<T>::IncrementHead( LPBUFFER_FLAGS pFlags )
{
ASSERT(this->m_pBuffer != NULL);
ASSERT(this->m_pStart != NULL);
ASSERT(this->m_pEnd != NULL);
ASSERT(this->m_tFlags.pHead != NULL);
ASSERT(this->m_tFlags.pTail != NULL);
pFlags = ( pFlags == NULL ) ? &(this->m_tFlags) : pFlags;
// Verify overrun condition is not set.
if ( pFlags->blOverrun == FALSE )
{
pFlags->pHead += sizeof(T); // increament buffer head pointer
pFlags->blUnderrun = FALSE; // clear underrun condition
// Correct for wrap condition.
if ( pFlags->pHead == this->m_pEnd )
{
pFlags->pHead = this->m_pStart;
}
// Check for overrun.
if ( pFlags->pHead == pFlags->pTail )
{
pFlags->blOverrun = TRUE;
}
}
}
在执行IncrementHead的pFlags->pHead += sizeof(T);时会出现上述问题。
【问题讨论】:
-
在没有看到类模板的实现的情况下无法确定,但对齐/填充是一种猜测。
-
你能提供一个小代码sn-p来演示这个问题吗,最好是没有任何其他依赖的可编译的?
-
发布你正在使用的实际代码
sizeof(T),以及你的类的完整定义。 -
某些东西可能正在为您重新定义 DWORD,但由于我们掌握的信息极其有限,因此无法判断。
-
我要出门了。当我明天早上第一件事时,我会为此发布一些代码。谢谢。
标签: c++ visual-studio-2008 templates sizeof circular-buffer