2013-02-19 18 views
10

Ich rufe strdup und muss Speicherplatz für die Variable vor dem Aufruf strdup reservieren.Wie verwende ich strdup?

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

Mache ich das richtig? Oder stimmt hier etwas nicht?

Antwort

17

Wenn Sie den POSIX-Standard strdup() verwenden, berechnet er den benötigten Speicherplatz und weist ihn zu und kopiert die Quellzeichenfolge in den neu zugewiesenen Speicherplatz. Sie müssen nicht selbst eine malloc() machen; In der Tat wird es sofort undicht, wenn Sie es tun, da Sie den einzigen Zeiger auf den Raum überschreiben, den Sie mit dem Zeiger dem Raum zugewiesen haben, der strdup() zugeteilt wurde.

Daraus folgt:

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

Wenn Sie die Speicherzuweisung müssen tun, dann müssen Sie strlen(word)+1 Bytes in variable zuordnen und Sie können dann kopieren word in diesem neu zugewiesenen Platz.

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

oder die Länge einmal berechnen und verwenden memmove() oder vielleicht 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); 

nicht, um sicherzustellen, Vergessen Sie wissen, wo die free() für jeden malloc() ist.

2

Wie es derzeit aussieht, leckt man immer 4 bis 8 Bytes (abhängig von Ihrer Architektur). Unabhängig von strdup, die will allocate the required dynamic memory on its own zuweisen Sie die einzige Variable, die den Zeiger auf Ihre neu Malloced Speicherbereich enthält neu zuweisen.

sagen einfach

char* const variable = strdup(word); 
9

Sie brauchen nicht Raum alloc für die Verwendung mit strdup, strdup wird, dass für Sie tun. Sie sollten es jedoch nach Gebrauch freigeben.

#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; 
} 

bearbeiten: Seien Sie vorsichtig mit C++ als der Variablenname neue Fein in C und nicht in C++, da es ein reservierter Name für Betreiber neu ist.

+0

Sie sollten nicht verwenden 'new' als Variablenname –

+0

@ Ale-batt Der Variablenname jedoch in C völlig in Ordnung ist, kann ich verstehe, dass der C++ - Compiler es nicht mag. Diese Frage wird mit C markiert. Daher sehe ich kein Problem. – hetepeperfan

6

Sie scheinen verwirrt. Vergessen Sie, was Sie über Zeiger wissen. Lass uns mit Ints arbeiten.

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

Gibt es eine Möglichkeit für uns, den alten Wert abzurufen, oder hat es „durchgesickert“ aus unserer Sicht? Nehmen wir einmal an, Sie sollten das Betriebssystem wissen lassen, dass Sie mit dieser Zufallszahl fertig sind, damit das Betriebssystem einige Bereinigungsaufgaben ausführen kann.

Ist der alte Wert für die Generierung des neuen Werts erforderlich? Wie kann es sein, wenn getchar x nicht sehen kann?

Wenden wir uns nun den Code betrachten:

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 

Gibt es für uns eine Möglichkeit, den alten Wert abzurufen, oder es „durchgesickert“ aus unserer Sicht hat?Es wird erwartet, dass Sie das Betriebssystem wissen lassen, wenn Sie mit dem Speicher malloc ed fertig sind, indem Sie free(variable); anrufen.

Ist der alte Wert für die Generierung des neuen Werts erforderlich? Wie kann es sein, wenn strdup Variable nicht sehen kann?

FYI, hier ist ein Beispiel dafür, wie strdup umgesetzt werden könnten:

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

    strcpy(duplicate, original); 
    return duplicate; 
}