-2

I have a byte* that I am saving into a char[]

printing the char[] I get

0,1023,1023,1000;0,0,1023,1000;1023,0,0,1000;1023,1023,0,1000;0,1023,0,1000

I pass that to a function using strtok to split on ";", saving that value to char *colorsAtTick;, then I am trying to save that into the array char *colorsAtTickArray[] = {}; by doing colorsAtTickArray[patternLength] = colorsAtTick;

But I get an error when trying to access colorsAtTickArray[i] in a loop.

The code is:

void callback(char* topic, byte* payload, unsigned int length) 
{
  //save payload bytes into char
  char pattern[length+1];
  for (int i = 0; i < length; i++) 
  {
    pattern[i] = (char)payload[i];
  }
  pattern[length+1] = '\0';
  Serial.print("this is the whole pattern: ");
  Serial.println(pattern);
  splitPatternTicks(pattern);
}

void splitPatternTicks(char *pattern) {
  char *colorsAtTick;
  char *colorsAtTickArray[] = {};
  //split pattern on ";" into chars
  colorsAtTick= strtok (pattern,";");
  while (colorsAtTick != NULL)
  {
    Serial.print("split on ; -->");
    Serial.println(colorsAtTick);
    //save the chars into an array
    colorsAtTickArray[patternLength] = colorsAtTick;

    patternLength ++;
    colorsAtTick = strtok (NULL,";");
  }
  for (int i = 0; i < patternLength; i ++) {
    //loop over the array of char to further split and save values
    //colorsAtTickArray ex. "255,0,0,1000"
    Serial.println("trying to parse values, sending ->");
    Serial.println(colorsAtTickArray[i]);
    //line above prints a blank line, then an error is thrown
    //parseTickValues(colorsAtTickArray[i], patternLength);
    //list[i] -> printObj();
  }
}

the terminal output:


This is the whole pattern:

0,1023,1023,1000;0,0,1023,1000;1023,0,0,1000;1023,1023,0,1000;0,1023,0,1000


split on ; -->0,1023,1023,1000

split on ; -->0,0,1023,1000

split on ; -->1023,0,0,1000

split on ; -->1023,1023,0,1000

split on ; -->0,1023,0,1000

trying to parse values, sending ->


Exception (28):
epc1=0x40208ccc epc2=0x00000000 epc3=0x00000000 excvaddr=0x0000000c depc=0x00000000

stack

ctx: cont
sp: 3ffffcf0 end: 3fffffc0 offset: 01a0
3ffffe90:  40203124 3ffee720 0000000c 402033f8  
3ffffea0:  3ffee608 3ffee720 3ffee720 40203465  
3ffffeb0:  3ffee608 3ffee720 00000000 40201224  
3ffffec0:  0000000c 0000004b 3ffee720 40203448  
3ffffed0:  0000000c 3ffee720 3ffee720 3fffff40  
3ffffee0:  0000000c 3ffee720 3ffffef0 40201290 <
3ffffef0:  30312c30 312c3332 2c333230 30303031  
3fffff00:  302c3000 3230312c 30312c33 31003030  
3fffff10:  2c333230 2c302c30 30303031 32303100  
3fffff20:  30312c33 302c3332 3030312c 2c300030  
3fffff30:  33323031 312c302c 00303030 6bc6a700  
3fffff40:  00000001 00005b68 3ffee60c 4020525c  
3fffff50:  3fffdad0 00005b68 3ffee60c 4020300c  
3fffff60:  007a1201 73c993ca 3ffee700 40202e90  
3fffff70:  00000004 3ffee60f 0000005b 402010b5  
3fffff80:  00000000 00000000 3ffee60c 3ffee798  
3fffff90:  3fffdad0 00000000 3ffee60c 402011a0  
3fffffa0:  3fffdad0 00000000 3ffee758 40203b80  
3fffffb0:  feefeffe feefeffe 3ffe84e8 40100bdd  
<<<stack<<<
⸮n⸮⸮⸮⸮⸮⸮

I was testing out what im trying to accomplish in a repl but I also have issues there as well (in this example only 2 of the 3 are printed) https://repl.it/@jordanklaers/arrayOfChars

phuclv
  • 37,963
  • 15
  • 156
  • 475
Jordan Klaers
  • 149
  • 11
  • The headline says `char* []` but your initial paragraph says `char[]`. Which is it? – Ted Lyngmo Nov 25 '19 at 23:16
  • 4
    `char *colorsAtTickArray[] = {};` does not do what you think it does. It does not, I repeat ***does not*** create an array of infinite size, that you can fill up, in the body of the `for` loop, as much as you want and without limit. That's not how arrays work in C++. This creates a completely empty array, and when the `for` loop proceeds to scribble all over it, this results in undefined behavior, and an eventual, guaranteed, crash. – Sam Varshavchik Nov 25 '19 at 23:16
  • 1
    You have a [problem of a non-constant length for your array](https://stackoverflow.com/q/57367473/10957435). –  Nov 25 '19 at 23:18
  • Also, see [this question](https://stackoverflow.com/q/57601909/10957435). –  Nov 25 '19 at 23:19
  • @SamVarshavchik actually it is ill-formed – M.M Nov 26 '19 at 00:27
  • @TedLyngmo that was the start of the process. If you read further I describe how the issue arrises from trying to save values into an empty char array "char *colorsAtTickArray[] = {}" so why the downvote? – Jordan Klaers Nov 26 '19 at 01:18
  • @JordanKlaers I haven't voted either way. – Ted Lyngmo Nov 26 '19 at 07:52
  • why am i getting downvoted? I'd like to ask better questions, can I get some constructive criticism to make things easier in the future? – Jordan Klaers Nov 27 '19 at 02:07
  • @JordanKlaers I can only guess, but you haven't really created a [mcve] as is mentioned in the [how to ask](https://stackoverflow.com/help/how-to-ask) guide. Your code contains irrelevant parts (`Serial` etc) - and all those part not affecting what you aim to demonstrate should be excluded. You however excluded the parts relevant for others to be able to copy/paste/compile your code as-is to be able to reproduce the problem themselves. Come to think of it, `Serial` sounds like an [arduino] thing, right? If so, add that tag. – Ted Lyngmo Nov 27 '19 at 11:03
  • Thank you, i'll make sure to correct those things next time I need help, sorry. – Jordan Klaers Nov 28 '19 at 06:13

2 Answers2

0

You have an off by 1 error.

pattern[length+1] = '\0';

This will overwrite past the end of your array and replace information on the stack causing your error
The last element in the pattern array will be pattern[length]
You have also included a common mistake in your for loop. Please see this article for an explanation

ron
  • 186
  • 7
  • I dont believe this is correct. I create pattern with "pattern[length+1]" and the loop goes to length so I am saving an extra space to add the '\0' – Jordan Klaers Nov 26 '19 at 01:25
  • Assuming Length is 1, so pattern[Length+1] will create an array of 2 elements. pattern[0] and pattern[1]. Now if you access Length+1 which is 2, you basicly write pattern[2], which will the the third element in a 2 element array., hope this helps – ron Nov 26 '19 at 05:28
0

Thanks to Sam Varshavchik and others who mentioned the issue I got past this by using

char *colorsAtTickArray[ticks];

where ticks is a variable representing the number of values

Jordan Klaers
  • 149
  • 11
  • If `ticks` in this answer == `patternLength` in the question, you are creating a VLA which is not part of standard C++ (but is available as an extension in some compilers). You'd better use `std::vector` for stuff like this if you want to create portable code. – Ted Lyngmo Nov 26 '19 at 08:01