Am I stepping outside the array boundary?

I am creating sine & cosine tables for fast look up in calculation with this bit of code:

#define BUFFER_LENGTH       2048

float cosine[BUFFER_LENGTH / 2];
float sine[BUFFER_LENGTH / 2];

void prepSineTables(size_t n) {
  for (int i = 0; i < n / 2; i++) {
		cosine[i] = (float)cos(2 * M_PI * i / n);
		sine[i] = (float)sin(2 * M_PI * i / n);
	}
}

when I call the prepSineTables() method with:

prepSineTables(BUFFER_LENGTH);

It crashes. Restricting the for-loop to read ‘i < 512’ runs fine, ‘i < 513’ crashes. Clearly I am stepping outside the array boundary, but why?

I know it crashes because the Photon is no longer responsive. I know it is this method that crashes because the testing harness calls this after a specified delay - prior to calling I publish a message which is visible on the dashboard so I know I am still alive.

When you say ‘Crashes’ what are the symptoms. If is is SOS folllowed by 1 flash I would suspect (due to recent experience) that with the rest of your code you have allocated too much memory.

Have you tried putting this in a small stub and executing it.

Accourding to @ScruffR issuing from the command line Particle compile… can give you some memory use stats.

Stan

crashes == I am getting the red SOS lights or sometimes the cyan blinking just stops and no further response.

This is in my main loop:

void loop() {

  m++;
  if ( m % 10 == 0)
  {
    publishMem();
    delay(2000);

    if (m == 100)
      prepSineTables(BUFFER_LENGTH);
  }
}

With publishMem() being:

void publishMem() {
  char publishString[100];

  sprintf(publishString, "Mem:%d", System.freeMemory() );
  Particle.publish("NbrDetail", publishString);
}

I introduced the loop counter and delay so I have time to see that the little booger is working up until I call that prep() method and that I have enough memory prior to that.

I’ll have to check - I can’t see anything obvious either.

Might have to do with the calculation aswell.

Is it an SOS+1, SOS+5 or SOS+9?


Update:
I’ve now tested on my own Photon with this code and can’t get an SOS of any sort

#include <math.h>

#define BUFFER_LENGTH       2048

float cosine[BUFFER_LENGTH / 2];
float sine[BUFFER_LENGTH / 2];

void prepSineTables(size_t n) {
  RGB.control(true);
  RGB.color(0, 0, 128);
  for (int i = 0; i < n / 2; i++) {
    cosine[i] = (float)cos(2 * M_PI * i / n);
    sine[i] = (float)sin(2 * M_PI * i / n);
  }
  delay(500);
  RGB.control(false);
}

void setup() {
  pinMode(D7, OUTPUT);
}

int m = 0;
void loop() {
  digitalWrite(D7, !digitalRead(D7));
  delay(500);
  if ((++m % 10) == 0)
    prepSineTables(BUFFER_LENGTH);   
}

Are you running this on a Spark Core and not a Photon?
That would explain why you run out of space with that size buffers.

What system version are you targeting?

For the future:
Your problems might not always be were you suspect them to be, so try to provide a fully runnable code (that exhibits the error) and not just some code fragments where you think the error might be.
Being more specific about your system (hardware, version, …) and the exact error code would help too.
It makes our (volunteer) job easier and helps you getting your answers quicker, since: “I can’t reproduce your error”, doesn’t help you or us really.

1 Like

@ScruffR: I am getting a SOS-1, I am sitting on a Photon.

Thanks and yes I understand that getting the problematic code in an entirely isolated example is much better for you volunteers but that by itself required some work/time I did not have. But this issue has given me a complete stop so I might as well work on getting it to fail in its own little project.

@ScruffR: here is my ‘isolated example’ on the Photon in three small files:

main.ino:

#include "math.h"
#include "dsp.h"

#define BUFFER_LENGTH       2048            // samples

float cosine[BUFFER_LENGTH/2];
float sine[BUFFER_LENGTH/2];
int m = 0 ;

STARTUP( WiFi.selectAntenna(ANT_AUTO) );

void setup() {

}

void loop() {
  m++;
  if ( m % 10 == 0)
  {
    delay(2000);
    publishMem();
    if (m == 50)
      prepSineTables(BUFFER_LENGTH);
  }
}

void publishMem() {
  char publishString[100];

  sprintf(publishString, "Mem:%d", System.freeMemory() );
  Particle.publish("MemDetail", publishString);
}

dsp.h

#ifndef __DSP_H__
#define _DSP_H__

#include "application.h"

void prepSineTables(int n);

#endif

dsp.cpp:

#include "dsp.h"
#include "math.h"

extern double cosine[];
extern double sine[];

void prepSineTables(int n) {
  for (int i = 0; i < n/2; i++) {
    cosine[i] = (float)cos(2 * M_PI * i / n);
	sine[i] = (float)sin(2 * M_PI * i / n);
	}
}

The loop simply goes through 5 iterations before it calls prepSineTables(). There is really no need for a loop, I just want to have the time to see all is working well before calling the offending function.

I have also used this flavor which fails in the same way:

  void prepSineTables(int n) {
     for (int i = 0; i < n/2; i++) {
        cosine[i] = 0;
    	sine[i] = 0;
    }
  }

But limiting the for-loop to half the buffer length works (just hardcoded to 512):

  void prepSineTables(int n) {
     for (int i = 0; i < 512; i++) {
        cosine[i] = (float)cos(2 * M_PI * i / n);
    	sine[i] = (float)sin(2 * M_PI * i / n);
    }
  }

Never mind - found it. Can’t believe I missed this. The dsp.h declares the arrays as doubles, not floats. Dang. I blame this to too much python and swift coding as of late (cough cough).

2 Likes

@joos I have been in IT for just under 40 years and the number of times I have seen (and have done it myself) the ‘Doh!’ moments where you start to explain your problem to someone else and half way thru…

I could almost write a book about them!

The other debugging event that occurred on my 21st birthday - I had a Db problem that I had been working on for 2 weeks - my colleagues took me out to lunch - and I had (quite a) few beers. When I got back to the office I immediately fixed the problem!

1 Like

Ah Stan, you’re my kinda man - beers to solve the problem. I have a few good Belgium ones in the fridge, going to get one now. I might need a few :wink:

My sort of tongue in cheek remark on blaming it on python and swift programming isn’t entirely unintentional though. The older I get the more these little details are annoying the crap out of me, I just want to solve the big problems. Python and (to some degree) Swift keep me out of trouble a lot more than C (and certainly C++). I am constantly in these three environments switching languages, hats and what not else. A bit challenging sometimes. But ScruffR’s back to basics message was well put and needed.

Anyway, the world is sane again.

1 Like