title: Reverse a string using pointers in a function, output in main is garbled
body: <p>I'm trying to self-study C using <a href="https://rads.stackoverflow.com/amzn/click/com/1571691618" rel="nofollow noreferrer" rel="nofollow noreferrer">C Primer Plus</a> from Stephen Prata and one of the end-of-chapter exercises is to "Write a function that replaces the contents of a string with the string reversed.".  This is a chapter on character strings with a good dose of pointers.  I'm trying to use pointers as much as possible so I can better understand, but I'm stuck.</p>
  
  <p>My problem is that when I print the value of the return pointer in main, it is garbled.</p>
  
  <p>When I use gdb(just learning how to use that too), I can see that the memory address returned from my function is the same address that was used in the function and it's getting assigned to my pointer in main okay as far as I can tell.  </p>
  
  <p>I've tried so many things, what am I missing?  FWIW I have not learned about malloc yet in the book, though I see it referenced on various www pages I've frequented trying to better understand C. </p>
  
  <pre><code>
  $ cc -o exercise8 exercise8.c && ./exercise8
  This is s1 before: abcd
  This is s2 in function: dcba
  This is s3 after: d`!</pre>
  
  <pre><code>
  /*   A function that replaces the contents of a string with the string reversed. */
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  char *str_rev(char * string);
  int main(void)
  {
     char * s1  = "abcd";
     char * s3;
     printf("This is s1 before: %s\n", s1);
  
     s3 = str_rev(s1);
     printf("This is s3 after: %s\n", s3);
  
  }
  
  char *str_rev(char * string)
  {
     char ar3[5];
     char * s2;
     int len = 0;
  
     s2 = ar3;
  
     len = (strlen(string) - 1);
     string = string + len;
  
     while ( len >= 0 )
     {
        *s2 = *string;
        len--;
        string--;
        s2++;
     }
     s2++;
     *s2 = 0;
     s2 = s2 - 5;
  
     printf("This is s2 in function: %s\n", s2);
     return s2;
  }
  </code></pre>
  
  <pre>
  $ gdb exercise8
  GNU gdb (GDB) 7.1-ubuntu
  
  Reading symbols from exercise8...done.
  (gdb) break 12
  Breakpoint 1 at 0x804844a: file exercise8.c, line 12.
  (gdb) break 40
  Breakpoint 2 at 0x80484d9: file exercise8.c, line 40.
  (gdb) run
  Starting program: exercise8
  This is s1 before: abcd         // My original string.
  This is s2 in function: dcba        // Good, my reversed string while in the function.
  
  Breakpoint 2, str_rev (string=0xbffff043 "dcba") at exercise8.c:40
  40               return s2;
  (gdb) print s2
  $1 = 0xbffff043 "dcba"          // Location of pointer s2.
  (gdb) continue
  Continuing.
  
  Breakpoint 1, main () at exercise8.c:12
  12               printf("This is s3 after: %s\n", s3);
  (gdb) print s3
  $2 = 0xbffff043 "dcba"          // Back in main same pointer as s2 from function.
  (gdb) step
  This is s3 after: d`Q           // Line 12 executed.  Output garbled.
  14      }
  (gdb)
  </code></pre>