Wie zu beheben strcpy so, dass es erkennt überlappende strings

In einem interview wurde ich gebeten, zu schreiben, der eine Implementierung von strcpy und dann fixieren Sie es so, dass es richtig behandelt überlappende strings. Meine Implementierung ist unten und es ist sehr naiv. Wie kann ich es beheben, so dass:

  1. Es erkennt überlappende strings und
  2. nach erkennen, wie gehen wir mit der überlappung und gehen?

char* my_strcpy(char *a, char *b) {

     if (a == NULL || b == NULL) {
         return NULL;
     }
     if (a > 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;
}

EDIT:

Also eine mögliche Umsetzung auf der Grundlage @Secure Antwort ist:

char* my_strcpy(char *a, char *b) {

    if (a == NULL || b == NULL) {
        return NULL;
    }

    memmove(a, b, strlen(b) + 1);
    return a;
}

Wenn wir verlassen uns nicht auf memmove, dann

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 <= b && a + strlen(a) > 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 <= a && b + strlen(b) > 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;
    }
}
  • Wie ist a > b sollen "erkennen, ein überlappen"? Es werden lediglich tests der beiden Adressen.
  • Kann man zwei Kopien: kopieren Sie zuerst zu einem lokalen Puffer, keine chance zu überlappen, dann aus dem lokalen Puffer auf das Ziel zu.
  • könnte man, aber dann my_strcpy müsste erlaubt sein, zu scheitern ENOMEM.
  • stimmt - "Es gibt kein solches Ding wie ein freies Mittagessen gibt"; obwohl dabei zwei Kopien ist sehr weit von einem kostenlosen Mittagessen in den ersten Platz 🙂
  • In Bezug auf Ihre Bearbeitung, wie ein interviewer meine nächste Frage wäre: Warum sollte man sich nicht darauf verlassen, memmove, und stattdessen den Handel one-liner gegen einen wartbaren Zeiger Umgang mit Chaos?
  • eigentlich...möchte ich Erstens verlassen sich auf memmove und wenn der interviewer fragt nach der blutigen details oder besteht kann ich nicht verwenden Sie memmove ich würde geben eine detaillierte Umsetzung...btw..ist die Umsetzung oben korrigieren?
  • Richtig? Ich Bezug auf die Portabilität, wie gesagt, Sie sind Berufung auf Undefiniertes Verhalten, wenn die zwei Zeiger sind aus verschiedenen arrays. Es gibt einen offensichtlichen Fehler, bist du mit strlen(a), aber das ist einfach zu lösen. *dest = '\0'; legt das erste byte des a, nicht auf das Letzte byte. Aber am wichtigsten ist, Sie ' ve verpasst den Fall, dass die strings sich nicht überlappen...
  • Für den Fall, wo Sie sich nicht überlappen würden, werden umgesetzt in der gleichen Weise, wie case1. Allerdings bin ich nicht in der Lage zu visualisieren, der zweite Fall(eine ist weiter im Speicher)..daher der Fehler codieren.Ich machte einige änderungen, aber ich werde es zu schätzen wissen wenn Sie mir helfen können visualisieren, Fall 2
  • Ich habe bearbeitet Sie meine Antwort mit einer Visualisierung der Fall ist 2.
  • Hinweis: if(a == NULL || b == NULL){ return NULL; } ist nicht erforderlich, wenn a, b Punkt-zu-C-strings.
  • Sollte nicht die "char *dest = a;" am Ende der entsprechenden Ziel-und count-down von dort aus, wenn Sie den Countdown von der aktuellen position, bist du nicht Puffer-unter-fließt?

InformationsquelleAutor user7 | 2011-09-15
Schreibe einen Kommentar