Arduino multi-dimensional array crash - arduino
I have a block of code that does something to this effect:
int pieceX = 0;
int pieceY = 0;
int board[8][47] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
if (pieceX > 0 && pieceY < 46) {
/* If I remove this it doesn't crash */
if (board[pieceX-1][pieceY] == 0 && board[pieceX][pieceY+1] == 0) {
pieceX -= 1;
}
/*-----------------------------------*/
}
As far as I can tell, I'm initializing my array correctly and I'm staying within the index bounds. I don't work much with Processing or Arduino, so I'm hoping it's something simple / obvious.
Edit: Hmm.. I just made a minimalistic test version with this code, and it doesn't crash. So, it's something to do with the code not in this example. Damn. Going to try to zero in on those lines. (My bad for posting this before properly isolating the problem code.) While this accurately describes the problem, it does not reproduce it. Strange bug.
Edit 2: This doesn't crash:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
if (board[0][0] == 0) {
}
}
}
This doesn't crash:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
pieceX -= 1;
}
}
This DOES crash:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
if (board[0][0] == 0) {
pieceX -= 1;
}
}
}
Any idea what's going on? ButtonA is never HIGH, so.. the code I'm tweaking shouldn't even matter (it all verifies and uploads fine.)
Edit 3: This crashes:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
if (board[0][0] == 0) {
pieceX -= 1;
}
}
}
This DOES NOT:
if (0 == 1) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
if (board[0][0] == 0) {
pieceX -= 1;
}
}
}
This crashes:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
if (board[0][0] == 0) {
pieceX = 1;
}
}
}
This DOES NOT:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
pieceX = 1;
}
}
AND THIS DOES NOT:
if (buttonA == HIGH) {
if (pieceX > 0 && pieceX < 8 && pieceY > 0 && pieceY < 46) {
if (board[0][0] == 0) {
}
}
}
Edit, here's the full source code. I'm only a few hours into a black and white Dr Mario clone. I never write in this language, so.. potentially a bit sloppy. More of a random learning experiment in processing / video game hardware / arduino.
Since the issue seems to be erratic, I would guess you are corrupting your stack.
I am not sure which Arduino you are using and how many other variables you have defined.
The array you are creating is 8 * 47 * 2 = 752 bytes, the Arduino Uno has 2048 ram bytes for the stack and all of your variables.
Edit:
Can you temporary reduce the size of the array(maybe 4 * 10) to see if it stops crashing?
Another test you could do is to list the values before you modify them and verify they are all 0.
This definitely looks like you are running out of memory.
int board[8][47]
consumes 752 bytes of memory. In addition
TV.begin(NTSC,120,96);
will call
char TVout::begin(uint8_t mode, uint8_t x, uint8_t y) {
// check if x is divisable by 8
if ( !(x & 0xF8))
return 1;
x = x/8;
screen = (unsigned char*)malloc(x * y * sizeof(unsigned char));
which tries to allocate 1440 bytes of memory. 1440 + 752 == 2192 > 2048 == SRAM size of Arduino
So you are running out of memory.
Can you switch int board[8][47] from int to int8_t or uint8_t? This would reduce the memory consumption of the array by 2. However you would still be very tight on memory.
This definitely looks like you are running out of memory.
You might be able to use less memory.
It looks like any given board element is either a 0 or 1.
If I am wrong disregard the rest of my statement.
Else you "could" make an array like this.
char board [47];
first = 0b00000001; //binary mask, for binary and
second = 0b00000010;
third = 0b00000100;
...
Then to look up any bit you
if (board[33]&second == 0 ) \\you are testing what was called board[2][33]
This might help you out.
Related
Failed to verifying the occurrence of a value in an array with logic function
I tried to use Frama-c to prove the occurrence of true value in an array that is the same as a integer which used to record the number of true values. But the prove failed if I want to change some values false to true. Is there any method to solve this problem? (Frama-c 25.0 / Alt-Ergo 2.4.2 / CVC4 1.8 / Z3 4.8.6) #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define SIZE 150 bool table[SIZE] = {true}; int true_counter; /*# logic integer count_true(integer idx) = idx<=0 ? 0 : (table[idx-1]==true ? count_true(idx-1) + 1 : count_true(idx-1)); */ /*# requires table[0] == false; requires true_counter == count_true(SIZE); assigns table[0], true_counter; ensures table[0] == true; ensures true_counter == \old(true_counter) + 1; */ void ATEST(void) { int countBF = 0; int countAF = 0; /*# loop invariant 0 <= idx <= SIZE; loop invariant 0 <= countBF == count_true(idx) <= idx; loop assigns idx, countBF; loop variant SIZE - idx; */ for(int idx=0; idx<SIZE; idx++) { if(table[idx] == true) countBF += 1; } //# assert true_counter == countBF; table[0] = true; true_counter += 1; /*# loop invariant 0 <= idx <= SIZE; loop invariant 0 <= countAF == count_true(idx) <= idx; loop assigns idx, countAF; loop variant SIZE - idx; */ for(int idx=0; idx<SIZE; idx++) { if(table[idx] == true) countAF += 1; } //# assert true_counter == countAF; //# assert countAF == countBF + 1; } [kernel] Parsing test.c (with preprocessing) [rte:annot] annotating function ATEST [wp] 33 goals scheduled [wp] [Failed] Goal typed_ATEST_assert_2 Z3 4.8.6: Unknown (Qed:8ms) (cached) CVC4 1.8: Timeout (Qed:8ms) (10s) (cached) Alt-Ergo 2.4.2: Timeout (Qed:8ms) (10s) (cached) [wp] [Cache] found:17 [wp] Proved goals: 32 / 33 Qed: 26 (0.84ms-7ms-24ms) Alt-Ergo 2.4.2: 6 (7ms-13ms-27ms) (629) (interrupted: 1) (cached: 7) CVC4 1.8: 4 (20ms-28ms-30ms) (11375) (interrupted: 1) (cached: 5) Z3 4.8.6: 4 (10ms-20ms) (46252) (unknown: 1) (cached: 5)
The problem is that such a reasoning is not that direct. Here is what happen: when we write cell 0, WP creates a new memory whose properties are directly related to the old memory. The loop invariant of the first loop gives to the solver some information about the original memory, the loop invariant of the second loop gives information about the new memory. But for establishing the link between the two we need to learn something like "since only on value has changed, the remaining part has the same number of occurrences". Which is not possible with most SMT solvers. For this particular example, we can be brutal and directly push the information in the invariant of the second loop: /*# loop invariant 0 <= idx <= SIZE; loop invariant 0 <= countAF == count_true(idx) <= idx; // added: loop invariant idx >= 1 ==> countAF == 1 + count_true{Pre}(idx) <= idx; loop assigns idx, countAF; loop variant SIZE - idx; */ for(int idx=0; idx<SIZE; idx++) { if(table[idx] == true) countAF += 1; } Which allows to create the link between the number of occurrences in the pre-state with the current number of occurrences. A more elegant solution is to dedicate a bit of ghost code so that it applies to any location: /*# requires 0 <= loc < SIZE ; requires table[loc] == false; requires true_counter == count_true(SIZE); assigns table[loc], true_counter; ensures table[loc] == true; ensures true_counter == \old(true_counter) + 1; */ void ATEST(int loc) { int countBF = 0; int countAF = 0; /*# loop invariant 0 <= idx <= SIZE; loop invariant 0 <= countBF == count_true(idx) <= idx; loop assigns idx, countBF; loop variant SIZE - idx; */ for(int idx=0; idx<SIZE; idx++) { if(table[idx] == true) countBF += 1; } //# assert true_counter == countBF; table[loc] = true; true_counter += 1; /*# ghost /# loop invariant 0 <= i <= loc ; loop invariant count_true(i) == count_true{Pre}(i); loop assigns i; loop variant loc - i ; #/ for(int i = 0 ; i < loc ; i++); /# loop invariant loc < i <= SIZE ; loop invariant count_true(i) == 1 + count_true{Pre}(i); loop assigns i; loop variant SIZE - i ; #/ for(int i = loc+1 ; i < SIZE ; i++); */ /*# loop invariant 0 <= idx <= SIZE; loop invariant 0 <= countAF == count_true(idx) <= idx; loop assigns idx, countAF; loop variant SIZE - idx; */ for(int idx=0; idx<SIZE; idx++) { if(table[idx] == true) countAF += 1; } } On can also express lemmas to handle the problem. For example the following lemmas can provide enough information to solvers so that they can finish the proof: /*# lemma same_count{L1,L2}: \forall integer size; 0<= size < SIZE ==> (\forall integer i; 0 <= i < size ==> \at(table[i], L1) == \at(table[i],L2)) ==> count_true{L1}(size) == count_true{L2}(size); */ /*# lemma same_but_one{L1,L2}: \forall integer size; 0 <= size < SIZE ==> \forall integer i_diff; 0 <= i_diff < size ==> (\forall integer i; 0 <= i < size && i != i_diff ==> \at(table[i],L1) == \at(table[i],L2)) && \at(table[i_diff],L1) == false && \at(table[i_diff],L2) == true ==> count_true{L1}(size) + 1 == count_true{L2}(size); */ The first lemma states that an unchanged memory region keeps the same number of occurrences as before. The second states that when in a state a cell has true while in another it is false and all remaining cells are the same, the number of occurrences changes by one. These two lemmas can be verified via the induction tactic (see for example https://stackoverflow.com/a/73796135/4628125). These two lemmas can be used directly by the solvers to get a proof for any location.
Game Of Life ends quickly (Java)
I've created a basic version of the Game Of Life: each turn, the board is simulated by a 2D array of 1's and 0's, after which another class creates a drawing of it for me using the 2d array I've read all the other questions here regarding this game, but no answer seems to work out for me....sorry if I'm beating a dead horse here. I think I have a problem with my algorithm, thus maybe the board gets filled with the wrong amount of dead and alive cells and thus ends rather quickly (5-10 turns). I've found an algorithm here to scan all the neighbors and even added a count = -1 in case it a cell in the grid scans itself as it's own neighbor, but I think I'm missing something here. public static void repaint(board game, int size,int[][] alive, int[][] newGeneration) { int MIN_X = 0, MIN_Y = 0, MAX_X =9, MAX_Y =9, count; for ( int i = 0; i < size; i++ ) { for (int j = 0; j < size; j++) //here we check for each matrix cell's neighbors to see if they are alive or dead { count = 0; if (alive[i][j] == 1) count = -1; int startPosX = (i - 1 < MIN_X) ? i : i - 1; int startPosY = (j - 1 < MIN_Y) ? j : j - 1; int endPosX = (i + 1 > MAX_X) ? i : i + 1; int endPosY = (j + 1 > MAX_Y) ? j : j + 1; for (int rowNum = startPosX; rowNum <= endPosX; rowNum++) { for (int colNum = startPosY; colNum <= endPosY; colNum++) { if (alive[rowNum][colNum] == 1) count++; } } if (alive[i][j] == 0 && count == 3) //conditions of the game of life newGeneration[i][j] = 1; //filling the new array for the next life if (alive[i][j] == 1 && count < 2) newGeneration[i][j] = 0; if (alive[i][j] == 1 && count >= 4) newGeneration[i][j] = 0; if (alive[i][j] == 1 && count == 3) newGeneration[i][j] = 1; } } game.setAlive(newGeneration); //we created a new matrix with the new lives, now we set it SetupGUI(game,size); //re drawing the panel } } What am I doing wrong? thanks for the help.
What exactly 0 && checksum != stored_checksum do?
http://www.vegardno.net/2017/03/fuzzing-openssh-daemon-using-afl.html diff --git a/packet.c b/packet.c --- a/packet.c +++ b/packet.c ## -1635,7 +1635,7 ## ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) cp = sshbuf_ptr(state->incoming_packet) + len - 4; stored_checksum = PEEK_U32(cp); - if (checksum != stored_checksum) { + if (0 && checksum != stored_checksum) { error("Corrupted check bytes on input"); if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 || (r = ssh_packet_write_wait(ssh)) != 0) Can someone please explain what does this patch do?: It removes this: - if (checksum != stored_checksum) { and adds this: + if (0 && checksum != stored_checksum) { What exactly 0 && checksum != stored_checksum do?
Explanation for crashing at n = 16
I am having a trouble in completing a homework of mine in C.The task is given an integer n print all the binary numbers with the length n that do not have 2 consecutive zeros int them and that includes leading zeros, note that at least one of the functions has to be recursive. Here is an example if n is 4 then the binary number 10 is treated 0010 and therefore wont be printed because it has 2 leading zeros. My problem is that my code crashes if n = 16 and I do not know why even though I have done a lot of debugging. Here is my code, Thanks for any help here. void binaries_n_digits_no_00(int n) { if(n < 0) { return; } print_binaries_n_digits_no_00(0,n); } void print_binaries_n_digits_no_00(long int current_binary_index,int n) { int num_of_leading_zeros; if((current_binary_index > (power(2,n) - 1)) || n == 0) { return; } num_of_leading_zeros = n - binary_num_length(current_binary_index); if((binary_not_contain_00(current_binary_index) == 1) && (num_of_leading_zeros == 1 || num_of_leading_zeros == 0)){ if(current_binary_index == 0 && n == 1) { printf("\n0"); } else if(num_of_leading_zeros == 1) { if(current_binary_index != 0) { printf("\n0"); print_binary(current_binary_index); } } else{ printf("\n"); print_binary(current_binary_index); } } print_binaries_n_digits_no_00(current_binary_index+1,n); } int binary_not_contain_00(long int num) { if(num/2 == 0) { return 1; } if(((num%2) == 0) && (((num/2) % 2) == 0)) { return 0; } return binary_not_contain_00(num/2); } void print_binary(long int num) { if(num > 1) { print_binary(num/2); } printf("%d",num%2); } int binary_num_length(long int num) { if(num <= 1) { return 1; } else{ return (1 + binary_num_length(num/2)); } } long int power(int m, int n) { if(n == 0) { return 1; } return m * power(m,n-1); }
Wrong number returns from EEPROM.get arduino
In the setup function i clear the EEPROM if a specific button is clicked. in the loop function at the start i have this code: if(millis() - last_sample >= 180){ sampler(); EEPROM.get(stateEEPROMAdress, stateCode); stateCode = getState(stateCode); EEPROM.put(stateEEPROMAdress, stateCode); Serial.println(stateCode); } and a bunch of sampling code. then at the end of the loop i have: if(millis() - last_xbee >= 900){ EEPROM.get(packetEEPROMAdress,packetCount ); EEPROM.get(stateEEPROMAdress,stateCode); if(!initializing || (stateCode!= 0 && stateCode != 1)){ telemetry[2] = packetCount++;} telemetry[21] =stateCode; EEPROM.put(packetEEPROMAdress, packetCount); .... and printing codes... I also at the start of the sketch i have defined : const int packetEEPROMAdress = 0; const int stateEEPROMAdress = packetEEPROMAdress + sizeof(int); and this is the getState function. simple state determination from sensor values: int getState(const int stateCode=0){ int outState; //state 0 if(stateCode == 0 &&(fabs(verticalSpeed) < 2 || fabs(relativeAltitude) < 5)&&initializing){ outState = 0; //true should change later to see is launch botton is on } else if(missionReady && !initializing && stateCode == 0){ outState = 1; }else if(verticalSpeed > 3&&stateCode == 1){ outState = 2; } //else //if(VerticalSpeed < 3 && stateCode == 2){ // stateCode = 2; // //apogee but no code in CDR //} else if(verticalSpeed < 2 &&stateCode == 2){ outState = 3; } else if((fabs(relativeAltitude - 450)< 10 || relativeAltitude<440 ) &&stateCode == 3){ outState = 4; }else //true should be replaced with seperation photocell is bright if(true && stateCode == 4){ outState = 5; }else if(relativeAltitude < 3 && fabs(verticalSpeed) < .7 && stateCode == 5 ){ outState == 6; //activate Buzzer stop telemetry } return outState; } everything a good when state is 0 . when i send a command and states becomes 1. the after a few loops that 1 appears. the number in EEPROM becomes 8663 . is there a problem in addressing the EEPROM?
It was sth silly:) Nothing related to EEPROM. I didn't give a initial value to outState so large number stored in EEPROM, Sorry if i got your time:)