mardi 29 août 2017

memory allocated for std::vector which in a map can not be released.

I use some data structures to store images of defective products in an inspection application. The data structure store defect information in defectDB_ and use a "url" point to imageDB_, which use std::vector to store actual image data. The problem is: I use imageDB_.erase() to erase the element, but the vector's memory is not released, the memory usage increased very fast. The following is "DB" definition:

// sourceId[0~3],defectRect,defectImageUrl,defectString
using DefectVector = std::vector<std::tuple<int, QRect, QString, QString>>;
//image(data,w,h,pitch,channel)
using ImageData = std::tuple<std::vector<uchar>, int, int, int, int>;
// productId:defectVector
std::map<int,DefectVector> defectDB_;
// imageUrl:
std::map<QString,ImageData> imageDB_;

The following codes store some images into memory. The std::vector is used to store the actual image data.

if (!thumb.isNull())
{

    QString key = QString("%1/%2/%3/%4").arg(id).arg(sourceId).arg(imageUrl).arg("thumb");
    imageDB_[key] = std::make_tuple(std::vector<uchar>(), thumb.width(), thumb.height(), thumb.bytesPerLine(),
        thumb.format() == QImage::Format_Grayscale8 ? 1 : 3);
    // allocate a buffer
    std::get<0>(imageDB_[key]).resize(thumb.height()*thumb.bytesPerLine());
    // copy to the buffer
    std::memcpy(std::get<0>(imageDB_[key]).data(), thumb.bits(), thumb.height()*thumb.bytesPerLine());


}

In the other place, I erased some items in imgeDB_ when there are too many images. The codes:

if (defectDB_.size() > MAX_DEFECTS_COUNT)
{
    auto head = defectDB_.begin();
    auto list = head->second;
    for (auto t : list)
    {
        auto url = std::get<2>(t);
        auto it = imageDB_.find(url);
        if (it != imageDB_.end())
        {
            imageDB_.erase(it);
        }
        else {
            qCritical() << "Missed image for image url:" << url;
        }
    }
    defectDB_.erase(head);
}

It seems the memory allocated by

std::get<0>(imageDB_[key]).resize(thumb.height()*thumb.bytesPerLine());

is never released! Anyone can help me to figure it out?

Aucun commentaire:

Enregistrer un commentaire