memory leak issue (WebPDecodeRGBA)
-
The following function works correctly, but causes a memory leak.
bool CBackground::decodeWebp(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, 0); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } int width = 0, height = 0; uchar* decodedData = WebPDecodeRGBA(reinterpret_cast<uchar*>(imageData.data()), imageSize, &width, &height); if (!decodedData) { throw std::runtime_error("Failed to decode WebP image"); return false; } m_pBkgndImage = new QImage(decodedData, width, height, width*4, QImage::Format_RGBA8888); //delete[] decodedData; //free(decodedData); //WebPFree(decodedData); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false
My guess is that decodedData isn't properly memory reclaimed.
All three of these statements raise an error.delete[] decodedData; free(decodedData); WebPFree(decodedData);
All three result in the same error.
std::invoke<<lambda_38ab7bdc6751b55a090baff38190ee7f> &> type_traits 1525 0x7ffd0c563e14
It's hard to understand why webpfree throws an error.
The decodeJpeg function below does not leak memory.
bool CBackground::decodeJpeg(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, Qt::Uninitialized); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } if (m_pBkgndImage != nullptr) { m_pBkgndImage = nullptr; } m_pBkgndImage = new QImage(QImage::fromData(imageData)); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false; }
How can i solve this problem?
-
The following function works correctly, but causes a memory leak.
bool CBackground::decodeWebp(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, 0); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } int width = 0, height = 0; uchar* decodedData = WebPDecodeRGBA(reinterpret_cast<uchar*>(imageData.data()), imageSize, &width, &height); if (!decodedData) { throw std::runtime_error("Failed to decode WebP image"); return false; } m_pBkgndImage = new QImage(decodedData, width, height, width*4, QImage::Format_RGBA8888); //delete[] decodedData; //free(decodedData); //WebPFree(decodedData); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false
My guess is that decodedData isn't properly memory reclaimed.
All three of these statements raise an error.delete[] decodedData; free(decodedData); WebPFree(decodedData);
All three result in the same error.
std::invoke<<lambda_38ab7bdc6751b55a090baff38190ee7f> &> type_traits 1525 0x7ffd0c563e14
It's hard to understand why webpfree throws an error.
The decodeJpeg function below does not leak memory.
bool CBackground::decodeJpeg(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, Qt::Uninitialized); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } if (m_pBkgndImage != nullptr) { m_pBkgndImage = nullptr; } m_pBkgndImage = new QImage(QImage::fromData(imageData)); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false; }
How can i solve this problem?
@MyNameIsQt
I solved the problem by creating it by copy rather than by reference. Of course, this caused the image not to show full size, but this will be fixed soon. thank youuint8_t* decodedData = WebPDecodeRGBA(reinterpret_cast<uchar*>(imageData.data()), imageSize, &width, &height); if (!decodedData) { throw std::runtime_error("Failed to decode WebP image"); return false; } m_pBkgndImage = new QImage(width, height, QImage::Format_RGBA8888); memcpy(m_pBkgndImage->bits(), decodedData, width * height * 4); WebPFree(decodedData);
-
The following function works correctly, but causes a memory leak.
bool CBackground::decodeWebp(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, 0); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } int width = 0, height = 0; uchar* decodedData = WebPDecodeRGBA(reinterpret_cast<uchar*>(imageData.data()), imageSize, &width, &height); if (!decodedData) { throw std::runtime_error("Failed to decode WebP image"); return false; } m_pBkgndImage = new QImage(decodedData, width, height, width*4, QImage::Format_RGBA8888); //delete[] decodedData; //free(decodedData); //WebPFree(decodedData); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false
My guess is that decodedData isn't properly memory reclaimed.
All three of these statements raise an error.delete[] decodedData; free(decodedData); WebPFree(decodedData);
All three result in the same error.
std::invoke<<lambda_38ab7bdc6751b55a090baff38190ee7f> &> type_traits 1525 0x7ffd0c563e14
It's hard to understand why webpfree throws an error.
The decodeJpeg function below does not leak memory.
bool CBackground::decodeJpeg(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, Qt::Uninitialized); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } if (m_pBkgndImage != nullptr) { m_pBkgndImage = nullptr; } m_pBkgndImage = new QImage(QImage::fromData(imageData)); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false; }
How can i solve this problem?
Hi @MyNameIsQt,
It appears (just looking at the docs; untested). That:
- the leak is, indeed, that
decodedData
needs to be freed. As per the WebPDecodeRGBA docs
The code that calls any of these functions must delete the data buffer (
uint8_t*
) returned by these functions withWebPFree()
.- the error you get having free'd it, is because
QImage
is still accessing the (now free'd) memory, long after your function has finished. As per the QImage docs
The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer. The image does not delete the buffer at destruction. You can provide a function pointer cleanupFunction along with an extra pointer cleanupInfo that will be called when the last copy is destroyed.
So, you either need to duplicate the buffer, and remember to clean it up later, or explore passing
&WebPFree()
(or your own function / lambda) to theQImage()
constructor so the QImage instance will delete it later.Cheers.
- the leak is, indeed, that
-
Hi @MyNameIsQt,
It appears (just looking at the docs; untested). That:
- the leak is, indeed, that
decodedData
needs to be freed. As per the WebPDecodeRGBA docs
The code that calls any of these functions must delete the data buffer (
uint8_t*
) returned by these functions withWebPFree()
.- the error you get having free'd it, is because
QImage
is still accessing the (now free'd) memory, long after your function has finished. As per the QImage docs
The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer. The image does not delete the buffer at destruction. You can provide a function pointer cleanupFunction along with an extra pointer cleanupInfo that will be called when the last copy is destroyed.
So, you either need to duplicate the buffer, and remember to clean it up later, or explore passing
&WebPFree()
(or your own function / lambda) to theQImage()
constructor so the QImage instance will delete it later.Cheers.
@Paul-Colby OK. Thanks.
- the leak is, indeed, that
-
The following function works correctly, but causes a memory leak.
bool CBackground::decodeWebp(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, 0); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } int width = 0, height = 0; uchar* decodedData = WebPDecodeRGBA(reinterpret_cast<uchar*>(imageData.data()), imageSize, &width, &height); if (!decodedData) { throw std::runtime_error("Failed to decode WebP image"); return false; } m_pBkgndImage = new QImage(decodedData, width, height, width*4, QImage::Format_RGBA8888); //delete[] decodedData; //free(decodedData); //WebPFree(decodedData); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false
My guess is that decodedData isn't properly memory reclaimed.
All three of these statements raise an error.delete[] decodedData; free(decodedData); WebPFree(decodedData);
All three result in the same error.
std::invoke<<lambda_38ab7bdc6751b55a090baff38190ee7f> &> type_traits 1525 0x7ffd0c563e14
It's hard to understand why webpfree throws an error.
The decodeJpeg function below does not leak memory.
bool CBackground::decodeJpeg(QFile *pFile) { long imageSize = m_bkgndHeader.ImageSize; long imageAddress = getImageAddress(); if (!pFile->seek(imageAddress)) { throw std::runtime_error("Failed to seek to image data"); return false; } QByteArray imageData(imageSize, Qt::Uninitialized); if (pFile->read(imageData.data(), imageSize) != imageSize) { throw std::runtime_error("Failed to read image data"); return false; } if (m_pBkgndImage != nullptr) { m_pBkgndImage = nullptr; } m_pBkgndImage = new QImage(QImage::fromData(imageData)); if(m_pBkgndImage != nullptr){ return true; }else{ delete m_pBkgndImage; m_pBkgndImage = nullptr; return false; } return false; }
How can i solve this problem?
@MyNameIsQt
I solved the problem by creating it by copy rather than by reference. Of course, this caused the image not to show full size, but this will be fixed soon. thank youuint8_t* decodedData = WebPDecodeRGBA(reinterpret_cast<uchar*>(imageData.data()), imageSize, &width, &height); if (!decodedData) { throw std::runtime_error("Failed to decode WebP image"); return false; } m_pBkgndImage = new QImage(width, height, QImage::Format_RGBA8888); memcpy(m_pBkgndImage->bits(), decodedData, width * height * 4); WebPFree(decodedData);
-