Garbage in Serial monitor followed by reset

When uploading a slight variation of the code I had running fine, the arduino would print some garbage in the terminal when running, then restart itself. I tried reverting back to the last known working version of the code, but it was still giving this behavior. Here's a copy of what the serial monitor prints out (all motor speeds should be 10):

Booting up...
Motor 0 speed: 2000
Motor 1 speed: 2000
Motor 2 speed: 2000

X-axis distance:10
Y-axis distance:10
Z-Axis distance:1⸮C⸮닥⸮⸮⸮up...
Motor 0 speed: 2000
Motor 1 speed: 2000
Motor 2 speed: 2000

X-axis distance:

Here is the complete code including the changes I commented out.

#include "pitches.h"

byte directionPin[3] = {4,7,8};
byte stepPin[3] = {3,6,9};
int stepsPerMM[3] = {10,10,1};
int maxSpeed = 400;
int steps[3] = {0,0,0};
bool dir[3] = {false,true,true};   //dir should move + in the axis, !dir is - 
int motorToAdress = 0;
bool currentState[3] = {true,true,true}; //is it moving forwards?
int destination[3] = {0,0,0};
int location[3] = {0,0,0};
unsigned long curMicros;
unsigned long prevStepMicros[3] = {0,0,0};
unsigned int microsBetweenSteps[3] = {2000,2000,2000}; // microseconds

const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
int dataNumber = 0;
int targetSpeed(2000);

void setup() {
                                                                      //this is where the fun begins
     Serial.begin(9600);
     Serial.println("Booting up...");
     pinMode(3,OUTPUT);
     pinMode(4,OUTPUT);
     pinMode(6,OUTPUT);
     pinMode(7,OUTPUT);
     pinMode(8,OUTPUT);
     pinMode(9,OUTPUT);
     for (int i = 0; i < 3; i++){
      digitalWrite(stepPin[i],HIGH);
     }
                                                                    //check if motor 0 exceeds speed limit
     if (microsBetweenSteps[0] < maxSpeed){
      Serial.print("Max Speed Exceeded on motor 0, speed set to ");
      Serial.println(maxSpeed);
      microsBetweenSteps[0] = maxSpeed;
     }
     else{
      Serial.print("Motor 0 speed: ");
      Serial.println(microsBetweenSteps[0]);
     }
                                                                  //check if motor 1 exceeds speed limit
     if (microsBetweenSteps[1] < maxSpeed){
      Serial.print("Max Speed Exceeded on motor 1, speed set to ");
      Serial.println(maxSpeed);
      microsBetweenSteps[1] = maxSpeed;
     }
     else{
      Serial.print("Motor 1 speed: ");
      Serial.print(microsBetweenSteps[1]);
      Serial.println();
     }
                                                                //check if motor 2 exceeds speed limit
     if (microsBetweenSteps[2] < maxSpeed){
      Serial.print("Max Speed Exceeded on motor 2, speed set to ");
      Serial.println(maxSpeed);
      microsBetweenSteps[2] = maxSpeed;
     }
     else{
      Serial.print("Motor 2 speed: ");
      Serial.println(microsBetweenSteps[2]);
     }
     Serial.println();
}

void loop() {
  if (steps[0] > 0 || steps[1] > 0 || steps[2] > 0){    //if any motors are still moving
    MoveMotors();
  }
  else{                                                 //once all movement is done
    GetPosition();
    PositionToSteps();
  }
}

void SetSpeeds(){
  int temp;
  for (int i = 0; i <=3; i++){
    temp += (steps[i]*steps[i]);
  }
  temp = sqrt(temp);
  temp = temp / targetSpeed;
  for (int i = 0; i <=3; i++){
    microsBetweenSteps[i] = microsBetweenSteps[i] / temp;;
  }
}

void PositionToSteps(){                                   //converts distances to steps
  for(int i = 0; i <=3; i++){
    if (destination[i] >= 0){                             //if moving forward
      steps[i] = destination[i];
      currentState[i] = true;
    }
    else{                                                 //if moving backward
      steps[i] = -1 * destination[i];
      currentState[i] = false;
    }
    steps[i] = steps[i] * stepsPerMM[i];                   //multiply mm by steps per mm
  }
  Serial.print("Steps to move:");
  Serial.print(steps[0]);
  Serial.print(",");
  Serial.print(steps[1]);
  Serial.print(",");
  Serial.println(steps[2]);
}

void GetPosition(){                                 //populates the destination arrays
  for (int i = 0; i < 3; i++){
    destination[i] = 32005;
  }
  Serial.print("X-axis distance:");
  while (destination[0] > 32000){
    recvWithEndMarker();
    destination[0] = NumberIn();
  }
  Serial.println(destination[0]);
  
  Serial.print("Y-axis distance:");
  while (destination[1] > 32000){
    recvWithEndMarker();
    destination[1] = NumberIn();
  }
  Serial.println(destination[1]);
  
  Serial.print("Z-Axis distance:");
  while (destination[2] > 32000){
    recvWithEndMarker();
    destination[2] = NumberIn();
  }
  Serial.println(destination[2]);
  
  Serial.println("Moving by: ");
  Serial.print(destination[0]);
  Serial.print(",");
  Serial.print(destination[1]);
  Serial.print(",");
  Serial.println(destination[2]);
  //SetSpeeds();
}

void MoveMotors(){
  for (int i = 0; i < 3;i++){
    motorToAdress = i;
    if (steps[motorToAdress] > 0){
      bool moved = false;
      if (currentState[i]){
        moved = singleStep(microsBetweenSteps[motorToAdress],dir[motorToAdress]);
      }
      else{
        moved = singleStep(microsBetweenSteps[motorToAdress],!dir[motorToAdress]);
      }
      if (moved){
      steps[motorToAdress]--;
      }
    }
  }
}

bool singleStep(unsigned long stepspeed, bool direct) {                 //returns true if motor was stepped
  curMicros = micros();
    if (curMicros - prevStepMicros[motorToAdress] >= stepspeed) {       //if enough time has passed
      
        prevStepMicros[motorToAdress] = curMicros;
        
        if (direct){                                                    //set direction
          digitalWrite(directionPin[motorToAdress],LOW);
        }
        else{
          digitalWrite(directionPin[motorToAdress],HIGH);
        }

        digitalWrite(stepPin[motorToAdress],HIGH);                      //pulse the pin
        digitalWrite(stepPin[motorToAdress],LOW);
        return true;
    }
    else{
      return false;
    }
}




void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
   
    if (Serial.available() > 0) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}
int NumberIn() {
    if (newData == true) {
        dataNumber = 0;             // new for this version
        dataNumber = atoi(receivedChars);   // new for this version
        //Serial.println(dataNumber);     // new for this version
        newData = false;
        return dataNumber;
    }
    return 32005;
}

Thanks for any insight you can give, and sorry the code is so long.
EDIT: I forgot to mention that I unplugged everything except for the USB cable during these tests.

You have multiple for loops going out of bounds with arrays:

for(int i = 0; i <=3; i++)

EDIT: Karma awarded for a properly documented issue and code tag usage.

Danois90:
You have multiple for loops going out of bounds with arrays:

for(int i = 0; i <=3; i++)

Thank you, I don't know how I didn't catch that earlier. I removed all the "=" so it was just < 3, and it runs without crashing.