我有一个 C++ 应用程序,我正在读取pcap
文件格式和处理 USB 数据包。对于每个数据包,我想创建一个QListWidgetItem
用于存储一些数据的数据包,然后将其添加到QListWidget
. 这就是麻烦开始的地方。根据 QListWidget 文档,插入 item 后:
列表小部件将拥有该项目的所有权。
所以我的想法是QListWidget
删除所有QListWidgetItems
. 这些项目添加得很好,但是当我关闭我的应用程序时(我想那是在调用 desctructor odQListWidget
所以他正在调用每个 desctructor 的时候QListWidgetItem
)我得到delete_scalar exception
. 根据调用堆栈,删除一些 QListWidgetItem 会触发它:
我的代码片段(为 pcap 文件中的每个数据包调用此函数,并负责创建和添加项目):
void ItemManager::ProcessPacket(QByteArray packetData)
{
const unsigned char* packet = (unsigned char*)packetData.data();
PUSBPCAP_BUFFER_PACKET_HEADER usbh = (PUSBPCAP_BUFFER_PACKET_HEADER)packet;
QListWidgetItem* item = new QListWidgetItem;
//set USBPCAP header to item
QByteArray usbhArray((const char*)packet, sizeof(USBPCAP_BUFFER_PACKET_HEADER));
item->setData(dataHolder->USBPCAP_HEADER_DATA, QVariant(usbhArray));
packet += sizeof(USBPCAP_BUFFER_PACKET_HEADER);
if (usbh->transfer == USBPCAP_TRANSFER_ISOCHRONOUS || usbh->transfer == USBPCAP_TRANSFER_CONTROL) //check for optional header data
{
int additionalDataSize = usbh->headerLen - sizeof(USBPCAP_BUFFER_PACKET_HEADER);
if (additionalDataSize > 0)
{
//set additional header data to item
QByteArray additionalDataArray((const char*)(packet), additionalDataSize);
item->setData(dataHolder->TRANSFER_OPTIONAL_HEADER, QVariant(additionalDataArray));
packet += additionalDataSize;
}
else
{
item->setData(dataHolder->TRANSFER_OPTIONAL_HEADER, QVariant()); //QVariant creates invalid QVariant, later i just need to check with QVariant::isValid()
}
}
else
{
item->setData(dataHolder->TRANSFER_OPTIONAL_HEADER, QVariant());
}
//set leftover data to item
QByteArray leftoverDataArray((const char*)packet, usbh->dataLength);
item->setData(dataHolder->TRANSFER_LEFTOVER_DATA, QVariant(leftoverDataArray));
listWidget->insertItem(listWidget->count(), item);
}
函数调用ProcessPacket
:
void ItemManager::ProcessFile(QString filename, bool liveReading)
{
if (fileReader.OpenNewFile(filename))
{
if (fileReader.ReadFileHeader())
{
while (!stopButtonClicked)
{
while (!fileReader.EndOfFile())
{
QByteArray packetData = fileReader.GetPacket();
if (!pauseButtonClicked)
{
ProcessPacket(packetData);
}
}
parent->Refresh(); //this is just calling QCoreApplication::processEvents();
if (!atBottomOfList)
{
listWidget->scrollToBottom();
}
if (liveReading)
{
Sleep(50);
}
else
{
return;
}
}
}
}
}
编辑
我发现这个问题只有在QListWidget
通过ItemManager
类附加时才会发生。在我的主要 Q_OBJECT 类USB_Packet_Analyzer
(它持有QlistWidget
我要附加到的)中,我有on_OpenButton_clicked()
如下所示的插槽:
void USB_Packet_Analyzer::on_OpenButton_clicked()
{
QString fil = QFileDialog::getOpenFileName(this, "Select source file", ".", "Pcap files (*.pcap)");
ItemManager manager(ui.listWidget,this);
manager.ProcessFile(fil, ui.liveCaptureRadioButton->isChecked());
}
在ItemManager
类构造函数中的位置如下所示:
ItemManager::ItemManager(QListWidget* listWidget, USB_Packet_Analyzer* parent)
{
this->stopButtonClicked = false;
this->pauseButtonClicked = false;
this->atBottomOfList = false;
this->listWidget = listWidget;
this->parent = parent;
this->dataHolder = DataHolder::GetDataHolder();
}
现在,如果我在on_OpenButton_clicked()
插槽中添加项目并关闭应用程序,一切都很好。但是当我ItemManager
在该类中创建实例并附加项目时,就会发生错误。难道是我不允许QListWidget*
作为参数传递?