Comments (7)
Hi @c-273 ,
Thank you for the detailed report. It's very interesting for me. Why it happened only on 64-bit? Anyway, I'm happy to hear that it did not occur in 3.9.0. I'm going to deprecate the 3.4.4 and release 4.0.0 as the next major release. If 3.9.0 is sufficient for your purpose, I'd like to ask you to use 3.9.0. Your further bug report is highly welcome.
from libqrencode.
No, it's not memory leak. When the program exits, the allocated buffer is released by the operating system. If we release it manually, we have to call free() at the very end of the main() of qrenc.c, and it is redundant.
from libqrencode.
I disagree - if you allocate memory then you should free it when no longer required. You should not depend on any operating system to do it for you!
There also appears to be a memory leak at the end of QRcode_encodeStringReal in grencode.c.
A solution is to call "QRcode_clearCache();" after every call to "QRinput_free(input);". In fact, probably need to call "QRcode_clearCache();" after every call to "QRinput_free(input);" throughout grencode.c.
from libqrencode.
@c-273 ,
To free the memory area pointed by "intext" in qrenc.c, we have to introduce a new variable to handle it for some reason ("intext" may point to an area allocated by the OS, not the application). Plus, the appropriate place to call free(intext) is at the very end of the main(), just before "return 0". It's too much redundant. See https://stackoverflow.com/a/2213836
BTW, the cache mechanism had been eliminated from the latest libqrencode.
Moreover, QRcode_clearCache() is not relevant to QRinput, as far as I understand. Please report the details if you still have a clear evidence of memory leaks.
from libqrencode.
Thank you.
I do have a memory leak (again 64-bit only, which I don't understand). However, it may well be that this call is required to be added by the user rather than the library but I couldn't find any documentation giving best practices e.g. stating something like: Initialise, Do something, Tidy up. It probably isn't in the library itself and so shouldn't be in this issue.
This is in the Windows version of wxWidgets - creating a wxBitmap from a Unicode string to display as a QR code. The wxWidgets version is only used by Linux users but I test it under Windows. It may well then be implemented in the MFC version of our Open Source application.
We convert the Unicode string to UTF8 format and generate a wxBitmap, which is then shown in a dialog. I have had to add 2 "QRcode_clearCache();" statements (marked ADDED below) to stop the memory leak (I think it is only the last one that is important).
wxBitmap QRCodeBitmap( const std::string &data )
{
using QRcodePtr = std::unique_ptr<QRcode, decltype(&QRcode_free)>;
using std::vector;
CUTF8Conv conv;
const unsigned char *utf8str = nullptr;
size_t utf8len = 0;
if ( !conv.ToUTF8(data, utf8str, utf8len) )
return wxBitmap();
auto qc_data = reinterpret_cast<const char *>(utf8str);
QRcodePtr qc(QRcode_encodeString8bit(qc_data, 0, QR_ECLEVEL_L), &QRcode_free);
if (!qc || !qc->width) {
QRcode_clearCache(); // ADDED
return wxBitmap();
}
constexpr unsigned margin = 24;
constexpr unsigned scale = 8;
// This is only for the ease of computation, to avoid filling and
// tracking bytes partially while generating the xbm data
static_assert( scale % 8 == 0, "QRcode must scale up by a factor of 8");
static_assert( margin % scale == 0, "margin must be a multiple of scale");
// in pixels
const unsigned imageWidth = 2 * margin + scale * qc->width;
const vector<char> pxTopMargin( (imageWidth*margin) / 8, 0 );
const vector<char> pxSideMargin( margin / 8, 0);
// This converts a line of QR data to a line of scaled-up pixels
// The last bit of QR byte, if 0 => white, else black
auto qr2xbmp = [&qc, scale](int line) {
vector<char> pixels(qc->width*scale / 8);
auto fill_index = pixels.begin();
auto from = qc->data + line*qc->width;
auto to = from + qc->width;
std::for_each(from, to, [&](char byte) {
const auto bytesToFill = scale / 8;
// All bits in these bytes are for the same pixel, so
// its either all 1s, or all 0s
std::fill_n(fill_index, bytesToFill, byte & 1? 0xff: 0);
std::advance(fill_index, bytesToFill);
});
return pixels;
};
vector<char> xbmp(pxTopMargin);
xbmp.reserve( imageWidth*imageWidth/8 );
// For each line of QR data, generate a line of pixels
for (auto line = 0; line < qc->width; ++line) {
vector<char> pxline(pxSideMargin);
pxline.reserve( imageWidth / 8 );
const auto qrdata = qr2xbmp(line);
wxASSERT( qrdata.size() == (imageWidth - 2 * margin) / 8 );
pxline.insert(pxline.end(), qrdata.begin(), qrdata.end());
pxline.insert(pxline.end(), pxSideMargin.begin(), pxSideMargin.end());
wxASSERT( pxline.size() == imageWidth / 8 );
// And repeat that line "scale" times
for (unsigned n = 0; n < scale; ++n)
xbmp.insert(xbmp.end(), pxline.begin(), pxline.end());
}
xbmp.insert(xbmp.end(), pxTopMargin.begin(), pxTopMargin.end());
QRcode_clearCache(); // ADDED
return wxBitmap(xbmp.data(), imageWidth, imageWidth);
}
...
from libqrencode.
Slight update.
- Memory leak happens in both 32-bit & 64-bit builds.
- The leak is at the end of the routine after inserting data into
xbmp
. I believe that the firstQRcode_clearCache();
is probably unnecessary as the creation of the QR code had failed (but I haven't had an occurrence when this has happened to test this). - If I use
QRcode
instead ofQRcodePtr
and then explicitly callQRcode_free();
before returning the wxBitmap rather than let it be called during the destruction of theQRcodePtr
when the routine ends, I still get the memory leak.
Thanks for your help with this.
PS. This is with V3.4.4 source of libqrencode compiled with both VS2015 & VS2017. You mentioned that "the cache mechanism had been eliminated from the latest libqrencode". Which version is this and when will it be formally released?
from libqrencode.
I can confirm that this memory leak has been fixed in version 3.9.0
from libqrencode.
Related Issues (20)
- Feature Request: QR decoder
- CLI option for mask pattern HOT 3
- qrencode produces invalid XPM data. HOT 2
- fish completions
- The width of the TWO-DIMENSIONAL code can be limited
- SVG version often rasterized with gaps HOT 3
- Request: Option to add image to the middle of the generated qr code
- rMQR Support
- ANSI and UTF8 types do not display properly on Windows HOT 2
- Please mention SVG output option in usage summary
- [Build Failed] Please consider updating autotool scripts.
- The library doesn't respect the encoding standard HOT 1
- Generation of lib and dll for windows
- Optimal text segmentation HOT 1
- Generate a QR code image with logo HOT 5
- Detect type of image from extension
- Setting --dpi has no effect on the PNG output HOT 2
- qrencode does not work with local linux vt/console
- Is it possible to use QRcode_encodeData() with command line tool (qrencode)?
- input string beginning with "-" parsed as option HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libqrencode.