StoreProhibitedCause 异常与 ESP8266 上的链表

StoreProhibitedCause Exception with linked list on ESP8266

我实现了一个链表 class 如下用于存储传感器数据读数。

(请注意,总代码约为 4000 行,因此我无法提供全部,希望这能让您了解已完成的工作)。

struct DataItem {
  String   _dataType;
  float    _dataArray[dataArraySize_const];
  float    _calibratedData = -1.0;
  float    _rawData        = -1.0;
  DataItem *_next;
  uint8_t  _dataArraySize = dataArraySize_const;
  float    *_calibrationParameters;
  uint8_t  _numCalibrationParameters;
};

class DataContainer {

  public:
    DataContainer() {
      _head = NULL;
      _tail = NULL;
    };

    DataItem* addDataItem(String dataTypeIn, float calibrationParameters[10], uint8_t numberOfCalibrationParameters) {
      DataItem *temp = new DataItem;

      temp->_dataType        = dataTypeIn;
      temp->_calibratedData  = -1.0;
      temp->_rawData         = -1.0;
      for (uint8_t i = 0; i < dataArraySize_const; i++) { temp->_dataArray[i] = 0; } //Setting all the data array to 0
      temp->_calibrationParameters    = calibrationParameters;
      temp->_numCalibrationParameters = numberOfCalibrationParameters;


      temp->_next = NULL;

      if(_head == NULL) {
        _head = temp;
        _tail = temp;
        temp = NULL;
      }
      else {    
        _tail->_next = temp;
        _tail = temp;
      }
      return temp;
    };

    uint8_t setDataValue(String dataType, float value, uint8_t arrayIndex) {
      DataItem *temp = new DataItem;
      temp = _head;
      Serial.println("Addresses: ");
      while(temp != NULL) {
        Serial.print("temp address:     0x");
        Serial.println((unsigned long)temp, HEX);
        Serial.print("head address:     0x");
        Serial.println((unsigned long)_head, HEX);
        Serial.print("temp add address: 0x");
        Serial.println((unsigned long)&temp, HEX);
        if      (temp->_dataType == dataType) { break; }
        else if (temp == NULL)                { return 1; }
        temp = temp->_next;
      }
      temp->_dataArray[arrayIndex] = value;

      float sum = 0.0;
      for (uint8_t i = 0; i < dataArraySize_const; i++) {
        sum += temp->_dataArray[i];
      }
      temp->_rawData = sum/dataArraySize_const;
      Serial.println("Pre calibration");
      this->calibrate(temp);
      Serial.println("Finished calibration");
      return 0;
    };

    void calibrate(DataItem *temp) {
      temp->_calibratedData = temp->_calibrationParameters[0];
      for (uint8_t i = 1; i <= temp->_numCalibrationParameters; i++) {
        temp->_calibratedData += temp->_calibrationParameters[i] * pow(temp->_rawData, i);
      }
    }

    uint8_t setCalibrationParameters(String dataType, float calibrationParameters[10]) {
      DataItem *temp = new DataItem;
      temp = _head;
      while(temp != NULL) {
        if      (temp->_dataType == dataType) { break; }
        else if (temp == NULL)                { return 1; }
        temp = temp->_next;
      }
      temp->_calibrationParameters = calibrationParameters;

      return 0;
    };


  private:
    DataItem *_head, *_tail;
};

uint8_t numUsedCalibrationParameters = 10;
float   calibrationParam[numUsedCalibrationParameters] = {0,1,0,0,0,0,0,0,0,0};

uint8_t dataArrayPosition = 0;
uint8_t dataArraySize     = 10;

void setup(void) {
  Serial.begin(115200);
  Serial.setDebugOutput(false);
  delay(20);
  Serial.println("\n\nbegin");
  pinMode(A0, INPUT);
  dataContainer.addDataItem("ADC",calibrationParam,numUsedCalibrationParameters);

void loop(void) {
  dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);

  if (dataArrayPosition < dataArraySize) { ++dataArrayPosition; }
  else                                   { dataArrayPosition = 0; }

  delay(100);
}

在大约 31000 次循环后(不到 2^15,这对我来说是可疑的),我得到了 StoreProhibitedCause 异常。如果我注释掉 dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);,我将不再得到异常。我怀疑这是我实现链表的某种方式,它有内存问题,但我已经尝试打印出所有内容的地址,但看起来 运行 没有任何东西。

异常:

Exception (29):
epc1=0x4000df64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3fffec10 end: 3fffffb0 offset: 01a0
3fffedb0:  4024576b 3fff0b08 00000002 40245700 
.....

===================== 已解决 ===================== DataItem *temp = new DataItem; 对于 setDataValue()setCalibrationParameters() 应该是 DataItem *temp;

否则它会继续为每次添加创建新结构。

对于 setDataValue()setCalibrationParameters().

DataItem *temp = new DataItem; 应该是 DataItem *temp;

否则它会继续为每次添加创建新结构。

(我无法在没有答案的情况下将其标记为已解决)。