Skip to content

Pull Request: Fix memory leak in MjpegClass#2

Open
jkarsten wants to merge 3 commits into
ArvinDelavari:mainfrom
jkarsten:main
Open

Pull Request: Fix memory leak in MjpegClass#2
jkarsten wants to merge 3 commits into
ArvinDelavari:mainfrom
jkarsten:main

Conversation

@jkarsten
Copy link
Copy Markdown

@jkarsten jkarsten commented Oct 3, 2025

#Problem
Currently, MjpegClass::setup() allocates _read_buf with malloc(READ_BUFFER_SIZE) every time it is called, but never releases previously allocated memory.
When a MJPEG file is restarted in a loop, this leads to a gradual heap leak (≈1 KB per restart on ESP32). After ~200 restarts the device runs out of memory and crashes.

##Changes

Added cleanup in setup() to free(_read_buf) before allocating a new buffer.

Added a destructor ~MjpegClass() to ensure _read_buf is freed when the object is destroyed.

Changed return value of setup() to (_read_buf != nullptr) so it properly reports allocation failures.

##Modified code (excerpt):

bool setup(
Stream *input, uint8_t *mjpeg_buf, JPEG_DRAW_CALLBACK *pfnDraw, bool useBigEndian,
int x, int y, int widthLimit, int heightLimit)
{
_input = input;
_mjpeg_buf = mjpeg_buf;
_pfnDraw = pfnDraw;
_useBigEndian = useBigEndian;
_x = x;
_y = y;
_widthLimit = widthLimit;
_heightLimit = heightLimit;
_inputindex = 0;

// Prevent memory leak if setup() is called multiple times
if (_read_buf) {
    free(_read_buf);
    _read_buf = nullptr;
}

_read_buf = (uint8_t *)malloc(READ_BUFFER_SIZE);

return (_read_buf != nullptr);

}

// new destructor
~MjpegClass() {
if (_read_buf) {
free(_read_buf);
_read_buf = nullptr;
}
}

##Result

Heap usage on ESP32 remains stable across hundreds of looped video restarts.

No crashes due to gradual memory exhaustion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant