getting stacktrace in serial monitor

I decoded the ESP8266 stacktrace I was getting in serial monitor:

Decoding stack results
0x40211de4: operator new[](unsigned int) at ../../../../../dl/gcc-xtensa/libstdc++-v3/libsupc++/new_opv.cc line 33
0x40202219: SensorData::read_sensor_data::analogValues() at /var/folders/43/m1qv9zf53q19sqh6h9kg9pz80000gn/T/arduino_build_623045/sketch/read_sensor_data.cpp line 19
0x402022cc: loop() at /Users/seaurchin/Development/Arduino/wemos/soil_sensor_with_ads/soil_sensor_with_ads.ino line 21
0x40207b24: loop_wrapper() at /Users/seaurchin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.2/cores/esp8266/core_esp8266_main.cpp line 125

Looks like its pointing to this library read_sensor_data.cpp

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include "read_sensor_data.h"

Adafruit_ADS1115 ads;

namespace SensorData
{
void read_sensor_data::initializeADC() {
  ads.setGain(GAIN_TWOTHIRDS);
  ads.begin();
}

int* read_sensor_data::analogValues()
  {
  
      int* arr = new int[4];
      int16_t adc0, adc1, adc2, adc3;
      arr[0] = ads.readADC_SingleEnded(0);
      arr[1] = ads.readADC_SingleEnded(1);
      arr[2] = ads.readADC_SingleEnded(2);
      arr[3] = ads.readADC_SingleEnded(3);
      return arr;
  }

}

but I do not understand what is wrong here. :o

You can't define an (automatic) array (or any variable) within a function and pass a usable pointer back to the calling routine. As soon as the function goes out of scope, the storage for the array is released. Easiest is to make the array global. You could also define it a static within the function if you want to do it that way.

Edit
The new operator uses heap storage for your array and this storage may become fragmented. Thus, it is best avoided for small microcontrollers.

Edit 2. (crossed with @JohnWasser)
Contrary to what I implied earlier, storage created with new is not cleaned up. You are responsible for deleting it explicitly. If you use new in a loop without cleaning it up, the heap could become full.

I suspect you are not releasing the memory space that analogValues() allocated. Eventually you run out of memory and crash. When you are done with the array returned by analogValues() you should delete it.

How should I release the memory space that analogValues() allocated?
I am novoice in arduino c++ .. any help will be greatly appreciated.

seaurchin:
How should I release the memory space that analogValues() allocated?
I am novoice in arduino c++ .. any help will be greatly appreciated.

analogValues() returns an 'int *' pointing to an array. You didn't include the part of your sketch where the function was called so I don't know what you do with that pointer. You are likely saving it in a variable of type 'int *'. Let's assume you call that variable 'myPointer'. When you are done with the array, I think you are supposed to say "delete [] myPointer;"

seaurchin:
How should I release the memory space that analogValues() allocated?
I am novoice in arduino c++ .. any help will be greatly appreciated.

post all your code including "read_sensor_data.h" and your .ino file. Maybe a solution becomes clearer. There is a delete method corresponding to new.

the ino sketch

#include "read_sensor_data.h"

void setup() {
  Serial.begin(115200);
SensorData::read_sensor_data::initializeADC();
}

void loop() {
SensorData::read_sensor_data::analogValues();
}

and here is read_sensor_data.h header file.

namespace SensorData
{
  class read_sensor_data
  {
    public:
      static void initializeADC();
      static int* analogValues();
  };
}

int* arr = new int[4]; -> free(arr); // At after your done with your toys, put them away.

-jim lee

jimLee:
int* arr = new int[4]; -> free(arr); // At after your done with your toys, put them away.

-jim lee

'free()' should only be used with 'malloc()'.

Use 'delete' if using 'new' to create single objects, use 'delete[]' if using 'new' to create an array of objects.

Try changing loop() to:

void loop() {
  int *analogData = SensorData::read_sensor_data::analogValues();  // Returns pointer to allocated int array.
  delete [] analogData;  // Free the space allocated for the int array.
}

That should run much longer without running out of memory.

is delete [] analogData;
different then delete analogData; ?
though just

delete analogData;

worked !

MHotchin:
'free()' should only be used with 'malloc()'.

Use 'delete' if using 'new' to create single objects, use 'delete[]' if using 'new' to create an array of objects.

OMG! I must be getting tired. I looked at that and my brain said malloc()

-jim lee

jimLee:
OMG! I must be getting tired. I looked at that and my brain said malloc()

-jim lee

You wouldn’t have gone far wrong. I’ve just looked at the Arduino implementation of the new / delete operators. Just under the surface is malloc() and free()

Considering the hammering that the String class gets here, it is probably best to stay away from them all.

seaurchin:
is delete [] analogData;
different then delete analogData; ?
though just

delete analogData;

worked !

They don't seem to be different on an AVR Arduino:

void operator delete(void * ptr) {
  free(ptr);
}

void operator delete[](void * ptr) {
  free(ptr);
}

But they may be different on other processors. You should call the proper one for the data allocated.