由线程锁引起的内存泄漏踩坑

在Qt项目中定义了一个双向链表的数据结构实现了插入和提取的逻辑分离,天然支持多线程的读和写。

struct StreamNode
{
	
public:
	std::array arrayData;
	StreamNode* pPre = nullptr, * pNext = nullptr;
};

插入代码如下:

void LinkedStream::InsertNode(const array& d)
{
	StreamNode* temp = new StreamNode();
	temp->pPre = Head;
	temp->pNext = Head->pNext;
	copy(begin(d), end(d), begin(temp->arrayData));

	if (firstInsert)
	{
		firstInsert = false;
		plotSamplePtr = temp;
	}
	InsertLocker.lock();
	Head->pNext->pPre = temp;
	Head->pNext = temp;
	avilableLen++;
	InsertLocker.unlock();
}

提取代码如下:

Pack LinkedStream::extractData(int inlength)
{
	Pack res;
	if (inlength == -1)
	{
		PlotSampleLocker.lock();
		int i;
		while (plotSamplePtr->pPre != Head)
		{
			for (i = 0; i < 16; i++)
			{
				res[i].push_back(plotSamplePtr->arrayData[i] * UNITRESOL);
			}
			plotSamplePtr = plotSamplePtr->pPre;
		}
		PlotSampleLocker.unlock();
		showedLen += avilableLen;
		avilableLen = 0;
	}
	else
	{
		int extractLen = 0;
		if (avilableLen > 100)
			inlength = inlength + avilableLen / 20;
#ifdef PRINTSTREAMLENGTH
		qDebug() << avilableLen;
#endif // PRINTSTREAMLENGTH
		PlotSampleLocker.lock();
		while ((plotSamplePtr->pPre != Head) && (extractLen < inlength))
		{
			for (int i = 0; i < 16; i++)
			{
				res[i].push_back(plotSamplePtr->arrayData[i] * UNITRESOL);
			}
			extractLen++;
			StreamNode* temp = plotSamplePtr;
			plotSamplePtr = plotSamplePtr->pPre;
			if (m_record.load(memory_order_acquire))
			{
				if ((recordOffset + 1) <= recordBufSize)
				{
					recordingData[recordOffset++] = plotSamplePtr->arrayData;
				}
				else
				{
					emit sendRecordSeq(recordingData,recordOffset);
					recordOffset = 0;
				}

			}
			delete temp;
		}

		PlotSampleLocker.unlock();
		showedLen += extractLen;
		avilableLen -= extractLen;
	}
	return res;
}

由于释放资源的语句

StreamNode *temp = plotSamplePtr;

delete temp;

在PlotSampleLocker锁的作用域范围内,如果发生线程阻塞在没有任务队列机制确保代码一定会执行的情况下可能会直接掠过这段代码造成内存泄漏。

然而之前查看VS的内存快照,其中一个叫QObjectPrivate::SignalVector[]的对象类型分配了大量的内存,并且每次分配的字节大小相同。故一直以为是某个信号槽的数据传递发生了内存泄漏,找了半天原来还是自己的锅啊!

由线程锁引起的内存泄漏踩坑_第1张图片

总结:尽量不把资源释放放在线程锁之间。

你可能感兴趣的:(C++,qt,c++,内存泄漏)