diff --git a/wled00/FX.h b/wled00/FX.h index d7eebc4f..28410783 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -395,10 +395,10 @@ typedef struct Segment { }; uint16_t _aux0T; uint16_t _aux1T; - uint32_t _stepT; - uint32_t _callT; - uint8_t *_dataT; - uint16_t _dataLenT; + uint32_t _stepT = 0; + uint32_t _callT = 0; + uint8_t *_dataT = nullptr; + uint16_t _dataLenT = 0; } tmpsegd_t; private: diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index f31b1899..9a3a4ded 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -168,6 +168,7 @@ bool Segment::allocateData(size_t len) { if (data && _dataLen == len) return true; //already allocated //DEBUG_PRINTF("-- Allocating data (%d): %p\n", len, this); deallocateData(); + if (len == 0) return(false); // nothing to do if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) { // not enough memory DEBUG_PRINTF("!!! Effect RAM depleted: %d/%d !!!\n", len, Segment::getUsedSegmentData()); @@ -184,9 +185,13 @@ bool Segment::allocateData(size_t len) { } void Segment::deallocateData() { - if (!data) return; + if (!data) { _dataLen = 0; return; } //DEBUG_PRINTF("--- Released data (%p): %d/%d -> %p\n", this, _dataLen, Segment::getUsedSegmentData(), data); - free(data); + if ((Segment::getUsedSegmentData() > 0) && (_dataLen > 0)) { // check that we don't have a dangling / inconsistent data pointer + free(data); + } else { + DEBUG_PRINTF("---- Released data (%p): inconsistent UsedSegmentData (%d/%d), cowardly refusing to free nothing.\n", this, _dataLen, Segment::getUsedSegmentData()); + } data = nullptr; // WARNING it looks like we have a memory leak somewhere Segment::addUsedSegmentData(_dataLen <= Segment::getUsedSegmentData() ? -_dataLen : -Segment::getUsedSegmentData()); @@ -338,6 +343,7 @@ void Segment::stopTransition() { //DEBUG_PRINTF("-- Released duplicate data (%d): %p\n", _t->_segT._dataLenT, _t->_segT._dataT); free(_t->_segT._dataT); _t->_segT._dataT = nullptr; + _t->_segT._dataLenT = 0; } #endif delete _t; @@ -364,6 +370,7 @@ uint16_t Segment::progress() { void Segment::swapSegenv(tmpsegd_t &tmpSeg) { if (!_t) return; //DEBUG_PRINTF("-- Saving temp seg: %p (%p)\n", this, tmpSeg); + if (nullptr == &tmpSeg) { DEBUG_PRINTLN(F("swapSegenv(): tmpSeg is nullptr !!")); return; } // sanity check tmpSeg._optionsT = options; for (size_t i=0; i_segT) != &tmpSeg) { // update possibly changed variables to keep old effect running correctly _t->_segT._aux0T = aux0;