title: How is running printf changing values in my int variables?
body: <p>I'm coding in C for the first time for a class, using gcc as my compiler.  </p>
  
  <p>I would like to apologize in advance for being the 10,000,000th person to ask this question. </p>
  
  <p>For those not interested in reading all of this, I have emboldened the actual question (the last paragraph) below. </p>
  
  <p>My code is copied at the end of this question. I turned the assignment in with only a 10 int array, and the sort works correctly, but if I change it to an 11 length array, things get weird. For this question, I'm talking about how my code functions with an array of 11 numbers to be sorted.</p>
  
  <p>I'm experiencing an issue which I believe to have to do with poorly written code dealing with memory in an unpredictable/incorrect way. I found many stackoverflow questions with a similar problem, but after all my troubleshooting and searching I am still stuck. None of the questions I found had solutions that fixed my problem.  I also believe it's likely that my algorithm for merge sort is flawed and might be causing the problem, but I have not yet picked out what exactly I did wrong, as it works correctly sometimes. </p>
  
  <p>Most of the S.O. questions I looked at had to deal with passing a function scope address back out to a calling function, or declared-but-uninitialized variables. I have looked through my code and not found any instances of either of these issues, but I believe my issue to be of a similar nature.  </p>
  
  <p><strong>If I add a printf(" "); statement anywhere into my <code>merge()</code> function definition, the code sorts the array correctly.  The <code>printf</code> statement has to actually have at least one character in it, and has no effect if I put it in any other functions. What am I doing wrong in the code below that's allowing a simple call to printf to change the values being passed around by my functions?</strong></p>
  
  <p>Note:  I have compiled this in a linux environment with GCC as well as on windows with MinGW GCC, it performs differently in each situation, but in both situations it is broken and appears to be the same issue.</p>
  
  <p>The code for my simple merge sort implementation is as follows: </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  #define NUMVALS 11
  
  //function prototypes
  void printArrValues(int*, int);
  void mergeSort(int*, int, int);
  void merge(int*, int, int, int, int);
  void showArraySorting(int*);
  
  //define some data to sort
  int intArrValsDesc[NUMVALS]    = {10,9,8,7,6,5,4,3,2,1,0};
  int intArrValsAsc[NUMVALS]     = {1,2,3,4,5,6,7,8,9,10,11};
  int intArrValsPreset1[NUMVALS] = {6,6,2,2,1,1,6,2,1,1,4};
  int intArrValsPreset2[NUMVALS] = {13,99,23,1,57,29,19,456,9,9,34};
  
  //self explanatory
  int main() {
      //show a few different sorting scenarios    
      //showArraySorting(intArrValsAsc);
      //showArraySorting(intArrValsDesc);
      //showArraySorting(intArrValsPreset1);
      showArraySorting(intArrValsPreset2);
  
      return(0);
  } 
  
  /*
  ** function to sort array while outputting beginning state, 
  ** progress states, and finished state
  */
  void showArraySorting(int *intArrToSort) {       
      //output initial array values
      printf("Start: ");
      printArrValues(intArrToSort, NUMVALS);
  
      mergeSort(intArrToSort, 0, NUMVALS - 1);
  
      //output sorted array values
      printf("Finish: ");
      printArrValues(intArrToSort, NUMVALS);
      printf("-----------------\n");       
  }
  
  /*
  ** function to output each value in the argument int array to the 
  ** console in the current order via stdio in the format "[ a b c ... ]"
  */
  void printArrValues(int *intArrToPrint, int intNumValues) {
  
      //define iteration counter int for looping through the values array
      int i;
  
      //begin the line with bracket for aesthetics
      printf("[ ");
  
      //loop MAX times to print out the values 
      for (i = 0; i &lt; intNumValues; i++) {
  
          //print out each value with a space after it
          printf("%d ", intArrToPrint[i]);
      }
  
      //end the line with closing bracket 
      printf("]\n");
  }
  
  //function which implements the merge sort algorithm 
  //by keeping track of nested index ranges in the array to be sorted.
  //as sorting decisions are made, numbers are rearranged in the target array
  void mergeSort(int *intArrToSort, int intLeftStartIndex, int intRightEndIndex) {        
      //if the current index range hasn't yet honed down to a single index
      if (intLeftStartIndex &lt; intRightEndIndex) {
          //printf("\n");
          //find the remaining two indices required to split the argument index
          //range into two smaller ones
          int intLeftEndIndex = (intLeftStartIndex + intRightEndIndex) / 2;
          int intRightStartIndex = intLeftEndIndex + 1;
  
          //printf("[%d, %d] and [%d, %d]\n",intLeftStartIndex,intLeftEndIndex, intRightStartIndex, intRightEndIndex);
  
          //continue recursively breaking the array subsets down into smaller pieces
          mergeSort(intArrToSort, intLeftStartIndex, intLeftEndIndex);
          mergeSort(intArrToSort, intRightStartIndex, intRightEndIndex);
  
          //all recursion below this level has finished, so merge the current two array subsets
          merge(intArrToSort, intLeftStartIndex, intLeftEndIndex, intRightStartIndex, intRightEndIndex);
          //show the status of the sort
          printf("  sorting... ");
          printArrValues(intArrToSort, NUMVALS);
      }        
  }
  
  /*
  ** Function to re-order the broken down components of the merge sort
  ** by comparing them to each other and swapping values in the parent array.
  */
  void merge(int *intArrToSort, int intLeftStartIndex, int intLeftEndIndex, int intRightStartIndex, int intRightEndIndex) {
  
      //calculate and store the number of values in each subset of the array.
      int intLeftArrSize = intLeftEndIndex - intLeftStartIndex + 1;
      int intRightArrSize = intRightEndIndex - intRightStartIndex + 1;
  
      //keep track of the total number of ints being combined in this pass
      int intTotalSize = intRightEndIndex - intLeftStartIndex + 1;
  
      //create new arrays to stack the sorted values in
      int intArrLeft[intLeftArrSize], intArrRight[intRightArrSize];
      int i;      
  
      //copy values into new left array
      for (i = 0; i &lt; intLeftArrSize; i++) {
          intArrLeft[i] = intArrToSort[intLeftStartIndex + i];
      }
      //copy values into new right array
      for (i = 0; i &lt; intRightArrSize; i++) {        
          intArrRight[i] = intArrToSort[intRightStartIndex + i];
      }
  
      //define the ints to hold the current index for both the left
      //and right array subsets. 
      int intCurrentLeftIndex = 0;
      int intCurrentRightIndex = 0;
  
      //define the int to hold the "target" index, initialize it with the leftmost
      //index of the left array subset. this holds which position in intArrToSort
      //is about to be updated with a new, sorted value 
      int intTargetIndex = intLeftStartIndex;    
  
      //sentinel variable for while loop
      int intDone = 0;
  
      //loop until all numbers in the two array subsets have been sorted into intArrToSort
      while (intDone == 0) {        
          //check if the lowest uncombined value in the left array is lower than the one in the right array
          if (intArrLeft[intCurrentLeftIndex] &lt;= intArrRight[intCurrentRightIndex]) {
              //it is, so assign it to the current target position in the combined array
              intArrToSort[intTargetIndex] = intArrLeft[intCurrentLeftIndex];
  
              //increment the array's index counter to signal that another number has been combined
              intCurrentLeftIndex++;
  
              //check if the lowest uncombined value in the right array is lower than the one in the left array
          } else {
  
              //it is, so assign it to the current target position in the combined array
              intArrToSort[intTargetIndex] = intArrRight[intCurrentRightIndex];
  
              //increment the array's index counter to signal that another number has been combined
              intCurrentRightIndex++;
          }       
  
          //increment the target index to prevent overwriting the recently combined value
          intTargetIndex++;
  
          //if we've combined all but one item in the two array subsets 
          if (intCurrentLeftIndex + intCurrentRightIndex &gt;= intTotalSize - 1) {
  
              //don't iterate again through this while loop
              intDone = 1;
  
              //if the remaining item is in the left array
              if (intLeftArrSize - intCurrentLeftIndex &gt; 0) {
  
                  //copy its value to intArrToSort
                  intArrToSort[intTargetIndex] = intArrLeft[intCurrentLeftIndex];
  
                  //if the remaining item isn't in the left array
              } else {
  
                  //assume it's in the right array and copy its value to intArrToSort
                  intArrToSort[intTargetIndex] = intArrRight[intCurrentRightIndex];
              }
          }
      }
  }
  </code></pre>
  
  <p>I also welcome any related or unrelated criticism of my terrible code.</p>