2013-02-19 13 views
10

Dzwonię pod numer strdup i trzeba przydzielić miejsce dla zmiennej przed wywołaniem strdup.Jak korzystać ze strdup?

char *variable; 
variable = (char*) malloc(sizeof(char*)); 
variable = strdup(word); 

Czy robię to dobrze? Czy coś tu jest nie tak?

Odpowiedz

17

Jeśli używasz standardu POSIX strdup(), oblicza on potrzebną przestrzeń i przydziela ją i kopiuje łańcuch źródłowy do nowo przydzielonego miejsca. Nie musisz samodzielnie wykonywać malloc(); w rzeczywistości natychmiast wycieknie, jeśli to zrobisz, ponieważ nadpisujesz jedyny wskaźnik do przestrzeni przydzielonej za pomocą wskaźnika do przestrzeni przydzielonej przez użytkownika.

Stąd:

char *variable = strdup(word); 
if (variable == 0) …process out of memory error; do not continue… 
…use variable… 
free(variable); 

Jeśli trzeba wykonać alokacji pamięci, to trzeba przeznaczyć strlen(word)+1 bajtów variable i można skopiuj word w tym nowo przydzielonego miejsca.

char *variable = malloc(strlen(word)+1); 
if (variable == 0) …process out of memory error; do not continue… 
strcpy(variable, word); 
…use variable… 
free(variable); 

Albo obliczyć długość raz i używać memmove() czy może memcpy():

size_t len = strlen(word) + 1; 
char *variable = malloc(len); 
if (variable == 0) …process out of memory error; do not continue… 
memmove(variable, word, len); 
…use variable… 
free(variable); 

Nie zapomnij, aby zapewnić wiesz gdzie free() jest dla każdego malloc().

2

W obecnej postaci zawsze masz przecieki od 4 do 8 bajtów (w zależności od architektury). Bez względu na to, czy strdupwill allocate the required dynamic memory on its own zmieniasz przypisanie, jedyna zmienna, która posiada wskaźnik do twojego nowo wycentrowanego obszaru pamięci.

Wystarczy powiedzieć

char* const variable = strdup(word); 
9

nie trzeba do przestrzeni alloc do użytku z strdup, strdup zrobi to za Ciebie. Powinieneś jednak uwolnić go po użyciu.

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 

int main(){ 

    const char* s1= "Hello World"; 
    char* new = strdup (s1); 
    assert (new != NULL); 

    fprintf(stdout , "%s\n", new); 

    free (new); 
    return 0; 
} 

Edit: Bądź ostrożny z C++ jako zmienna nazwa nowego jest w porządku w C, a nie w C++, ponieważ jest to nazwa zastrzeżona dla operatora new.

+0

Nie należy stosować 'new' jako nazwy zmiennej –

+0

@ Ale-płatu Nazwa zmiennej jest perfekcyjnie w C. Jednak mogę rozumiem, że kompilator C++ go nie lubi. To pytanie jest oznaczone jako C. Dlatego nie widzę problemu. – hetepeperfan

6

Wydajesz się zdezorientowany. Zapomnij o tym, co wiesz o wskaźnikach. Pracujmy z ints.

int x; 
x = rand(); // Let us consider this the "old value" of x 
x = getchar(); // Let us consider this the "new value" of x 

Czy możemy odzyskać starą wartość, czy też "wyciekło" z naszego widoku? Jako hipotetyczny, załóżmy, że spodziewano się, że system operacyjny będzie wiedział, że skończyłeś z tą liczbą losową, aby system operacyjny mógł wykonać niektóre zadania porządkowania.

Czy stara wartość jest wymagana do wygenerowania nowej wartości? Jak to możliwe, gdy getchar nie widać x?

Rozważmy teraz swój kod:

char *variable; 
variable = (char*) malloc(sizeof(char*)); // Let us consider this the "old value" of variable 
variable = strdup(word);     // Let us consider this the "new value" of variable 

Czy jest jakiś sposób dla nas, aby pobrać starą wartość, czy jest to „wyciekły” z naszego punktu widzenia?Oczekuje się, że system operacyjny zostanie poinformowany, gdy skończysz z pamięcią, dzwoniąc pod numer: free(variable);.

Czy stara wartość jest wymagana do wygenerowania nowej wartości? Jak to możliwe, gdy strdup nie widzi zmiennej?

FYI, oto przykład, jak może być realizowany strdup:

char *strdup(const char *original) { 
    char *duplicate = malloc(strlen(original) + 1); 
    if (duplicate == NULL) { return NULL; } 

    strcpy(duplicate, original); 
    return duplicate; 
} 
Powiązane problemy