strdup() – wat doet het in C?

Wat is het doel van de functie strdup()in C?


Antwoord 1, autoriteit 100%

Precies hoe het klinkt, ervan uitgaande dat je gewend bent aan de verkorte manier waarop C en UNIX woorden toewijzen, dupliceert strings🙂

Onthoud dat het eigenlijk geen deel uitmaakt van de ISO C-standaard zelf(a)(het is een POSIX-ding), het doet in feite hetzelfde als de volgende code:

char *strdup(const char *src) {
    char *dst = malloc(strlen (src) + 1);  // Space for length plus nul
    if (dst == NULL) return NULL;          // No memory
    strcpy(dst, src);                      // Copy the characters
    return dst;                            // Return the new string
}

Met andere woorden:

  1. Het probeert voldoende geheugen toe te wijzen voor de oude string (plus een ‘\0’-teken om het einde van de string te markeren).

  2. Als de toewijzing is mislukt, wordt errnoingesteld op ENOMEMen wordt onmiddellijk NULLgeretourneerd. Het instellen van errnoop ENOMEMis iets wat mallocdoet in POSIX, dus we hoeven het niet expliciet te doen in onze strdup. Als je nietPOSIX-compatibel bent, verplicht ISO C het bestaan van ENOMEMniet echt, dus ik heb dat hier niet opgenomen(b).

  3. Anders werkte de toewijzing, dus we kopiëren de oude string naar de nieuwe string(c)en retourneren het nieuwe adres (waarvan de beller op een bepaald moment verantwoordelijk is voor het vrijgeven).

Houd er rekening mee dat dit de conceptuele definitie is. Elke bibliotheekschrijver die zijn salaris waard is, heeft mogelijk sterk geoptimaliseerde code geleverd die is gericht op de specifieke processor die wordt gebruikt.


(A) Functies die beginnen met stren een kleine letter worden gereserveerd door de standaard voor toekomstige aanwijzingen. Van C11 7.1.3 Reserved identifiers:

Elke header verklaart of definieert alle identificatienetjes die zijn vermeld in de bijbehorende subclausule en * optioneel verklaart of definieert identificatoren die zijn vermeld in de bijbehorende toekomstige bibliotheekrichtingen subclausule. **

De toekomstige aanwijzingen voor string.hzijn te vinden in C11 7.31.13 String handling <string.h>:

Functie-namen die beginnen met str, mem, of wcsen een kleine letter kan worden toegevoegd aan de aangiften in de <string.h>koptekst.

Dus u moet het waarschijnlijk iets anders noemen als u veilig wilt zijn.


(B) De wijziging zou in principe worden vervangen door if (d == NULL) return NULL;met:

if (d == NULL) {
    errno = ENOMEM;
    return NULL;
}

(C) Merk op dat ik strcpydaarvoor gebruik, omdat dat duidelijk de intentie toont. In sommige implementaties kan het sneller zijn (aangezien u al de lengte kent) om memcpyte gebruiken, omdat ze mogelijk de gegevens in grotere brokken of parallel kunnen overbrengen. Of het mag niet 🙂 Optimalisatie MANTRA # 1: “Meet, niet raden”.

In elk geval, mocht u besluiten om die route te gaan, zou u iets doen als:

char *strdup(const char *src) {
    size_t len = strlen(src) + 1;       // String plus '\0'
    char *dst = malloc(len);            // Allocate space
    if (dst == NULL) return NULL;       // No memory
    memcpy (dst, src, len);             // Copy the block
    return dst;                         // Return the new string
}

Antwoord 2, autoriteit 23%

char * strdup(const char * s)
{
  size_t len = 1+strlen(s);
  char *p = malloc(len);
  return p ? memcpy(p, s, len) : NULL;
}

Misschien is de code iets sneller dan met strcpy()omdat het teken \0niet opnieuw hoeft te worden doorzocht (het was al met strlen()).


Antwoord 3, autoriteit 14%

Het heeft geen zin de andere antwoorden te herhalen, maar houd er rekening mee dat strdup()alles kan doen wat het wil vanuit een C-perspectief, aangezien het geen deel uitmaakt van een C-standaard. Het wordt echter gedefinieerd door POSIX.1-2001.


Antwoord 4, autoriteit 5%

Van strdup man:

De functie strdup()retourneert een aanwijzer naar een nieuwe tekenreeks, die een duplicaat is van de tekenreeks waarnaar wordt verwezen door s1. De geretourneerde aanwijzer kan worden doorgegeven aan free(). Er wordt een null-pointer geretourneerd als de nieuwe tekenreeks niet kan worden gemaakt.


Antwoord 5

strdup() voert dynamische geheugentoewijzing uit voor de tekenreeks inclusief het eindteken ‘\0’ en retourneert het adres van het heapgeheugen:

char *strdup (const char *s)
{
    char *p = malloc (strlen (s) + 1);   // allocate memory
    if (p != NULL)
        strcpy (p,s);                    // copy string
    return p;                            // return the memory
}

Dus wat het doet is ons een andere string geven die identiek is aan de string die door zijn argument wordt gegeven, zonder dat we geheugen moeten toewijzen. Maar we moeten het later nog vrijmaken.


Antwoord 6

Het maakt een dubbele kopie van de ingevoerde string door een mallocen strcpyvan de ingevoerde string uit te voeren. vandaar de noodzaak om gratisuit te voeren op de retourwaarde.


Antwoord 7

strdupen strndupworden in POSIX-compatibele systemen gedefinieerd als:

char *strdup(const char *str);
char *strndup(const char *str, size_t len);

De functie strdup()wijst voldoende geheugen toe voor een kopie van de
string str, kopieert en geeft er een verwijzing naar terug.

De aanwijzer kan vervolgens worden gebruikt als argument voor de functie free.

Als er onvoldoende geheugen beschikbaar is, wordt NULLgeretourneerd en wordt errnoingesteld op
ENOMEM.

De functie strndup()kopieert maximaal len-tekens uit de tekenreeks strdie altijd null is waarmee de gekopieerde tekenreeks wordt beëindigd.


Antwoord 8

Het meest waardevolle dat het doet, is je een andere string geven die identiek is aan de eerste, zonder dat je zelf geheugen (locatie en grootte) hoeft toe te wijzen. Maar, zoals opgemerkt, je moet het nog steeds vrijmaken (maar waarvoor ook geen hoeveelheidsberekening vereist is.)


Antwoord 9

De verklaring:

strcpy(ptr2, ptr1);

is gelijk aan (behalve het feit dat dit de wijzers verandert):

while(*ptr2++ = *ptr1++);

Terwijl:

ptr2 = strdup(ptr1);

is gelijk aan:

ptr2 = malloc(strlen(ptr1) + 1);
if (ptr2 != NULL) strcpy(ptr2, ptr1);

Dus, als je wilt dat de tekenreeks die je hebt gekopieerd in een andere functie wordt gebruikt (zoals deze is gemaakt in de heap-sectie), kun je strdupgebruiken, anders strcpyis genoeg,


Antwoord 10

De functie strdup() is een afkorting voor tekenreeksduplicaat, het neemt een parameter op als een tekenreeksconstante of een letterlijke tekenreeks en wijst net genoeg ruimte toe aan de tekenreeks en schrijft de overeenkomstige tekens in de toegewezen ruimte en retourneert uiteindelijk het adres van de toegewezen ruimte aan de aanroepende routine.

Other episodes