strdup () - co robi w C?

Jaki jest cel strdup() funkcji w C?

Author: Grijesh Chauhan, 2008-10-31

10 answers

Dokładnie tak, jak to brzmi, zakładając, że jesteś przyzwyczajony do skróconego sposobu, w jaki C i UNIX przypisują słowa, to duplikuje ciągi :-)

Pamiętając, że w rzeczywistości nie jest częścią samego standardu ISO C(a) (jest to rzecz POSIX), skutecznie robi to samo, co następujący kod:

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

Innymi słowy:

  1. Próbuje przydzielić wystarczającą ilość pamięci do przechowywania starego ciągu znaków (plus znak '\0', aby zaznaczyć koniec Sznurka).

  2. Jeśli alokacja nie powiodła się, Ustawia errno na ENOMEM i natychmiast zwraca NULL. Ustawienie errno na ENOMEM jest czymś, co malloc robi w POSIX, więc nie musimy tego jawnie robić w naszej strdup. Jeśli nie jesteś zgodny z POSIX, ISO C w rzeczywistości nie nakazuje istnienia ENOMEM, więc nie uwzględniłem tego tutaj (b) .

  3. W Przeciwnym Razie alokacja zadziałała, więc kopiujemy Stary ciąg do nowego łańcucha i zwracamy nowy adres (za który dzwoniący odpowiada w pewnym momencie).

Należy pamiętać, że jest to definicja pojęciowa. Każdy autor bibliotek wart swojej pensji mógł dostarczyć mocno zoptymalizowany kod skierowany do konkretnego używanego procesora.


(a) Należy jednak pamiętać, że funkcje zaczynające się od str i małej litery są zarezerwowane przez standard dla przyszłych kierunków. Z C11 7.1.3 Reserved identifiers:

Każdy nagłówek deklaruje lub definiuje wszystkie identyfikatory wymienione w powiązanej subklauzie, a * opcjonalnie deklaruje lub definiuje identyfikatory wymienione w powiązanej subklauzie przyszłych instrukcji bibliotecznych.**

Przyszłe kierunki dla string.h można znaleźć w C11 7.31.13 String handling <string.h>:

Nazwy funkcji zaczynające się na str, mem, lub wcs i do deklaracji w nagłówku <string.h> można dodać małą literę.


(b) zmiana polegałaby w zasadzie na zastąpieniu if (d == NULL) return NULL; z:

if (d == NULL) {
    errno = ENOMEM;
    return NULL;
}
 326
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 09:45:48
char * strdup(const char * s)
{
  size_t len = 1+strlen(s);
  char *p = malloc(len);

  return p ? memcpy(p, s, len) : NULL;
}

Może kod jest nieco szybszy niż z strcpy(), ponieważ znak \0 nie musi być przeszukiwany ponownie(był już z strlen()).

 79
Author: Patrick Schlüter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-30 15:38:34

Nie ma sensu powtarzać innych odpowiedzi, ale proszę pamiętać, że strdup() może zrobić wszystko, co chce z perspektywy C, ponieważ nie jest częścią żadnego standardu C. Jest on jednak zdefiniowany przez POSIX.1-2001.

 50
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-02 14:26:25

From strdup man:

Funkcja strdup() zwraca wskaźnik do nowego ciągu znaków, który jest duplikatem ciągu znaków wskazywanego przez s1. Zwracany wskaźnik można przekazać do free(). Zwracany jest wskaźnik null, jeśli nie można utworzyć nowego ciągu znaków.

 16
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-02 16:31:28

Tworzy zduplikowaną kopię przekazanego ciągu, uruchamiając malloc i strcpy przekazanego ciągu. Bufor malloc ' AD jest zwracany do wywołującego, stąd potrzeba uruchomienia free na zwracanej wartości.

 3
Author: jussij,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-31 07:22:27

Strdup() wykonuje dynamiczną alokację pamięci dla tablicy znaków wraz ze znakiem końca "\0 " i zwraca adres pamięci sterty:

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
}

To, co robi, to daje nam kolejny łańcuch identyczny z łańcuchem podanym przez jego argument, bez konieczności przydzielania pamięci. Ale musimy go uwolnić później.

 3
Author: Karshit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-04 14:27:41

strdup i {[2] } są zdefiniowane w systemach zgodnych z POSIX jako:

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

Funkcja strdup () przydziela wystarczającą ilość pamięci na kopię string str, wykonuje kopię i zwraca do niej wskaźnik.

Wskaźnik może być następnie użyty jako argument funkcji free.

Jeśli dostępna jest niewystarczająca pamięć, zwracane jest NULL i errno jest ustawione na ENOMEM.

Strndup () funkcja kopiuje co najwyżej len znaki z string str zawsze null kończy kopiowany łańcuch.

 2
Author: Sujay Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 11:00:47

Najcenniejszą rzeczą, jaką robi, jest podanie kolejnego ciągu identycznego z pierwszym, bez konieczności samodzielnego przydzielania pamięci (lokalizacji i rozmiaru). Ale, jak wspomniano, nadal musisz go uwolnić (ale nie wymaga to również obliczenia ilości.)

 1
Author: dkretz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-31 07:27:02

Funkcja strdup() jest skrótem od duplikatu łańcuchów, przyjmuje parametr jako stałą łańcuchową lub literał Łańcuchowy i przydziela wystarczająco dużo miejsca na łańcuch i zapisuje odpowiednie znaki w przydzielonej przestrzeni i na koniec zwraca adres przydzielonej przestrzeni do funkcji wywołującej.

 1
Author: AnkitSablok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-13 05:49:36

To proste {[0] } jest równoważne while(*ptr2++ = *ptr1++)

Gdzie as: strdup jest równoważne

ptr2 = malloc(strlen(ptr1)+1);

strcpy(ptr2,ptr1);

Więc jeśli chcesz, aby skopiowany łańcuch został użyty w innej funkcji (tak jak jest utworzony w sekcji sterty), możesz użyć strdup, w przeciwnym razie strcpy wystarczy

 0
Author: Md. Al Amin Bhuiyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-03 09:04:04