我有一个名为SFrame的结构,它包含许多元素,特别是2个无符号字符*的元素。我在我的类中创建了这个结构的成员变量,但是我在我的类中的函数中的每次迭代时都重新初始化它(除非某个布尔值为真)。我这样做的方式如下:
if (false == m_bRemainderNeedsProcessing)
{
// ... calls before and after the initialization are unimportant and not shown
m_sFrame = SFrame();
}
然后我将m_sFrame传递给一个函数来分配它的一些元素,然后我需要在我的struct中为我的pszMessage变量分配一个unsigned char数组。
m_sFrame.iMessageSize = m_sFrame.iPayloadLength;
m_sFrame.iOriginalMessageSize = m_sFrame.iPayloadLength;
m_sFrame.pszMessage = new unsigned char[m_sFrame.iPayloadLength + Constants::RSSL_DECODE_PADDING];
m_sFrame.pszOriginalMessage = new unsigned char[m_sFrame.iPayloadLength + Constants::RSSL_DECODE_PADDING];
这些SFrame实例存储在SFrame的矢量中,即
std::vector<SFrame>;
我希望能够为每次迭代重用m_sFrame,但我必须确保如果我要清除SFrame的内容,那么当我将它存储在向量中时,SFrame会被复制到向量中而不会丢失它是指定的值。为此,我为SFrame创建了一个复制构造函数:
我附上了部分SFrame复制构造函数的图像。
在我的函数结束时,我通过执行以下操作清除pszMessage中的内存(以及几乎相同的pszOriginalMessage):
ClearMemory(m_sFrame.pszMessage);
ClearMemory函数执行以下操作:
void CPCAPParser::ClearMemory(unsigned char *pszBuffer)
{
if(pszBuffer != NULL)
{
delete [] pszBuffer;
}
}
问题是,这个函数似乎删除了它应该做的更多....因为经过多次迭代后,我得到一个未处理的异常:访问违规......
我附上了一些可能有助于传达问题的图片。真的需要帮助:(如果有人需要我添加更多细节,请告诉我。
由于
http://imageshack.com/f/pduGDLGZp(常量:: RSSL_DECODE_PADDING的长度为7,因此总共有13个字节已经设置 - 在内存块的开头显而易见。)
http://imageshack.com/f/exRaaEmip - 我在哪里调用ClearMemory(内存地址显然仍然相同)。
我会发布更多图片,但我没有足够的代表...
SFrame:
struct SFrame
{
int* ipTemp_int_ptr;
int* ipTemp_int_ptr_actual;
int* piTimestampPos;
int* piOffset;
int iIP_Header_Length;
int iTCP_Header_Length;
int iTCP_Source_Port;
int iTCP_Dest_Port;
long long uiSequenceNumber;
long long uiInitialSequenceNumber;
long long uiAckNumber;
int iIp_total_length;
int iActual_frame_length;
int iOriginal_frame_length;
int iCaptured_frame_length;
int iTotalPayloadLength;
int iTotalMsgLoad;
int iPayloadLength;
int iBytesComplete;
int iFragmentID;
int iRemainder;
int iMessageSize;
int iOriginalMessageSize;
long long iNextExpectedSequenceNum;
std::string strSourceAddress;
std::string strDestAddress;
std::string strTimestamp;
unsigned char* pszMessage;
unsigned char* pszOriginalMessage;
unsigned int uiClientID;
int iStartOfRemainder;
int iAccumulatedMsgLength;
SFrame() : ipTemp_int_ptr ( NULL ),
ipTemp_int_ptr_actual ( NULL ),
piTimestampPos ( NULL ),
piOffset ( NULL ),
pszMessage ( NULL ),
pszOriginalMessage ( NULL ),
iIP_Header_Length( 0 ),
iTCP_Header_Length ( 0 ),
iTCP_Source_Port ( 0 ),
iTCP_Dest_Port ( 0 ),
iIp_total_length ( 0 ),
iActual_frame_length ( 0 ),
iOriginal_frame_length ( 0 ),
iCaptured_frame_length ( 0 ),
uiSequenceNumber( 0 ),
uiInitialSequenceNumber ( 0 ),
uiAckNumber( 0 ),
iPayloadLength ( 0 ),
iNextExpectedSequenceNum ( 0 ),
uiClientID ( 0 ),
iMessageSize ( 0 ),
iOriginalMessageSize ( 0 ),
iFragmentID( 0 ),
iTotalPayloadLength( 0 ),
iBytesComplete( 0 ),
iAccumulatedMsgLength ( 0 ),
iRemainder ( 0 ),
iStartOfRemainder( 0 ),
iTotalMsgLoad ( 0 )
{
}
SFrame(const SFrame &c_rSrc)
{
*this = c_rSrc;
}
SFrame &SFrame::operator=(const SFrame &c_rSrc)
{
iIP_Header_Length = c_rSrc.iIP_Header_Length;
iTCP_Header_Length = c_rSrc.iTCP_Header_Length;
iTCP_Source_Port = c_rSrc.iTCP_Source_Port;
iTCP_Dest_Port = c_rSrc.iTCP_Dest_Port;
iIp_total_length = c_rSrc.iIp_total_length;
iActual_frame_length = c_rSrc.iActual_frame_length;
iOriginal_frame_length = c_rSrc.iOriginal_frame_length;
iCaptured_frame_length = c_rSrc.iCaptured_frame_length;
iPayloadLength = c_rSrc.iPayloadLength;
uiSequenceNumber = c_rSrc.uiSequenceNumber;
uiInitialSequenceNumber = c_rSrc.uiInitialSequenceNumber;
uiAckNumber = c_rSrc.uiAckNumber;
iNextExpectedSequenceNum = c_rSrc.iNextExpectedSequenceNum;
uiClientID = c_rSrc.uiClientID;
iFragmentID = c_rSrc.iFragmentID;
iMessageSize = c_rSrc.iMessageSize;
iOriginalMessageSize = c_rSrc.iOriginalMessageSize;
iTotalPayloadLength = c_rSrc.iTotalPayloadLength;
iBytesComplete = c_rSrc.iBytesComplete;
iAccumulatedMsgLength = c_rSrc.iAccumulatedMsgLength;
iRemainder = c_rSrc.iRemainder;
iStartOfRemainder = c_rSrc.iStartOfRemainder;
iTotalMsgLoad = c_rSrc.iTotalMsgLoad;
strSourceAddress = c_rSrc.strSourceAddress;
strDestAddress = c_rSrc.strDestAddress;
strTimestamp = c_rSrc.strTimestamp;
pszMessage = (c_rSrc.pszMessage == NULL) ? NULL : new unsigned char[c_rSrc.iMessageSize];
pszOriginalMessage = (c_rSrc.pszOriginalMessage == NULL) ? NULL : new unsigned char[c_rSrc.iOriginalMessageSize];
if(pszMessage != NULL)
{
memcpy(pszMessage, c_rSrc.pszMessage, c_rSrc.iMessageSize);
}
if(pszOriginalMessage != NULL)
{
memcpy(pszOriginalMessage, c_rSrc.pszOriginalMessage, c_rSrc.iOriginalMessageSize);
}
return *this;
}
~SFrame()
{
delete [] pszMessage;
delete [] pszOriginalMessage;
}
};
答案 0 :(得分:0)
您的问题是您的SFrame
结构不安全,但是您将这个实例放在std::vector
中进行复制。
或者:
SFrame
结构或std::vector
。现在你的结构中有很多成员。如果您在复制构造函数中只丢失了一个,或者您对已分配内存的处理有问题,那么您将获得一个损坏的副本。由于vector<SFrame>
会创建副本,因此使用vector<SFrame>
打印副本是不可能的。
所以不是这样,这是使用选项2的修复:
#include <vector>
struct SFrame
{
std::vector<int> ipTemp_int_ptr;
std::vector<int> ipTemp_int_ptr_actual;
std::vector<int> piTimestampPos;
std::vector<int> piOffset;
int iIP_Header_Length;
int iTCP_Header_Length;
int iTCP_Source_Port;
int iTCP_Dest_Port;
long long uiSequenceNumber;
long long uiInitialSequenceNumber;
long long uiAckNumber;
int iIp_total_length;
int iActual_frame_length;
int iOriginal_frame_length;
int iCaptured_frame_length;
int iTotalPayloadLength;
int iTotalMsgLoad;
int iPayloadLength;
int iBytesComplete;
int iFragmentID;
int iRemainder;
int iMessageSize;
int iOriginalMessageSize;
long long iNextExpectedSequenceNum;
std::string strSourceAddress;
std::string strDestAddress;
std::string strTimestamp;
std::vector<unsigned char> pszMessage;
std::vector<unsigned char> pszOriginalMessage;
unsigned int uiClientID;
int iStartOfRemainder;
int iAccumulatedMsgLength;
SFrame() :
iIP_Header_Length( 0 ),
iTCP_Header_Length ( 0 ),
iTCP_Source_Port ( 0 ),
iTCP_Dest_Port ( 0 ),
iIp_total_length ( 0 ),
iActual_frame_length ( 0 ),
iOriginal_frame_length ( 0 ),
iCaptured_frame_length ( 0 ),
uiSequenceNumber( 0 ),
uiInitialSequenceNumber ( 0 ),
uiAckNumber( 0 ),
iPayloadLength ( 0 ),
iNextExpectedSequenceNum ( 0 ),
uiClientID ( 0 ),
iMessageSize ( 0 ),
iOriginalMessageSize ( 0 ),
iFragmentID( 0 ),
iTotalPayloadLength( 0 ),
iBytesComplete( 0 ),
iAccumulatedMsgLength ( 0 ),
iRemainder ( 0 ),
iStartOfRemainder( 0 ),
iTotalMsgLoad ( 0 )
{
}
};
请注意,复制构造函数和赋值运算符(以及析构函数)现在已经消失,从而使代码更容易处理,并且在复制期间没有机会丢失任何成员。相反,我们让编译器生成副本,编译器将始终让每个成员都被复制。
现在,您的代码库必须重新编译,并且您将不可避免地遇到编译器错误。但是,这些错误通常很容易修复。大多数人可能会要求你
delete [] somepointer;
的行,其中somePointer
现在是向量和&vector[0]
或vector.data()
,因为向量基本上是new[]/delete[]
的包装。回到原始代码,您的赋值运算符的一个问题是您无法删除先前分配的内存,因此您有内存泄漏。另外,考虑到编写复制操作的方式,您没有检查自我分配。但是,这可能不是唯一的错误,因为我们没有看到您如何使用这些SFrame
个实例。
因此,最好更改为矢量,修复编译器错误,重建和测试应用程序。