title: How to fix strcpy so that it detects overlapping strings
body: <p>In an interview, I was asked to write an implementation of <a href="https://en.cppreference.com/w/c/string/byte/strcpy" rel="nofollow noreferrer"><code>strcpy</code></a> and then fix it so that it properly handles overlapping strings. My implementation is below and it is very naive. How do I fix it so that:</p>
  
  <ol>
  <li>It detects overlapping strings and</li>
  <li>after detecting, how do we deal with the overlap and proceed?</li>
  </ol>
  
  <hr>
  
  <pre><code>char* my_strcpy(char *a, char *b) {
  
       if (a == NULL || b == NULL) {
           return NULL;
       }
       if (a &gt; b) {
           //we have an overlap?
           return NULL;
       }
       char *n = a;
  
       while (*b != '\0') {
           *a = *b;
           a++;
           b++;
       }
       *a = '\0';
       return n;
  }
  
  int main(int argc, char *argv[])
  {
      char str1[] = "wazzupdude";
      char *after_cpy = my_strcpy(str1 + 2, str1);
      return 0;
  }
  </code></pre>
  
  <hr>
  
  <p><strong>EDIT:</strong></p>
  
  <p>So one possible implementation based on <strong>@Secure's</strong> answer is:</p>
  
  <pre><code>char* my_strcpy(char *a, char *b) {
  
      if (a == NULL || b == NULL) {
          return NULL;
      }
  
      memmove(a, b, strlen(b) + 1);
      return a;
  }
  </code></pre>
  
  <p>If we don't rely on <a href="https://en.cppreference.com/w/c/string/byte/memmove" rel="nofollow noreferrer"><code>memmove</code></a>, then </p>
  
  <pre><code>char* my_strcpy(char *a, char *b) {
  
      if (a == NULL || b == NULL) {
          return NULL;
      }
  
      if (a == b) {
          return a;
      }
  
      // case1: b is placed further in the memory
      if ( a &lt;= b &amp;&amp; a + strlen(a) &gt; b ) {
          char *n = a;
  
          while(*b != '\0') {
              *a = *b;
              a++; b++;
          }
          *a = '\0';
          return n;
      }
  
      // case 2: a is further in memory
      else if ( b &lt;= a &amp;&amp; b + strlen(b) &gt; a ) { 
          char *src = b + strlen(b) - 1; // src points to end of b
          char *dest = a;
  
          while(src != b) {
              *dest = *src;
              dest--; src--;  // not sure about this..
          }
          *a = '\0';
          return a;
      }
  }
  </code></pre>