【问题标题】:StoreProhibitedCause Exception with linked list on ESP8266ESP8266 上的链表出现 StoreProhibitedCause 异常
【发布时间】:2020-05-22 18:46:49
【问题描述】:

我已经实现了一个如下的链表类来存储传感器数据读数。

(请注意,总代码约为 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 
.....

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

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

【问题讨论】:

    标签: arduino esp8266 nodemcu arduino-esp8266


    【解决方案1】:

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

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

    (如果没有答案,我无法将其标记为已解决)。

    【讨论】:

    • 但你可以删除它
    • 但是如果其他人有同样的问题,它可能会帮助他们。
    • 这只是你的错误,不是问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 2018-05-09
    相关资源
    最近更新 更多