Как использовать strdup?

Я вызываю strdup и должен выделить место для переменной перед вызовом strdup.

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

Я делаю это правильно? Или здесь что-то не так?

Ответ 1

Если вы используете стандарт POSIX strdup(), он вычисляет необходимое пространство и выделяет его и копирует исходную строку в новую выделенное пространство. Вам не нужно делать malloc() самостоятельно; действительно, он сразу же течет, если вы это делаете, поскольку вы перезаписываете единственный указатель на пространство, которое вы выделили указателем на пространство, выделенное strdup().

Следовательно:

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

Если вам нужно выполнить выделение памяти, вам нужно выделить strlen(word)+1 байты в variable, и затем вы можете скопировать word в это новое выделенное пространство.

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

Или вычислите длину один раз и используйте memmove() или, возможно, 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);

Не забудьте убедиться, что вы знаете, где free() для каждого malloc().

Ответ 2

вам не нужно выделять пространство для использования с помощью strdup, strdup сделает это за вас. Однако вы должны освободить его после использования.

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

Изменить. Будьте осторожны с С++, поскольку имя переменной new отлично в C, а не в С++, поскольку это зарезервированное имя для нового оператора.

Ответ 3

Ты выглядишь смущенным. Забудьте о том, что вы знаете о указателях. Пусть работает с 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

Есть ли у нас способ получить старое значение или он "просочился" из нашего представления? Предположим, что вы ожидали, что ОС сообщит, что вы закончили с этим случайным числом, чтобы ОС выполнила некоторые задачи очистки.

Требуется ли старое значение для генерации нового значения? Как это может быть, когда getchar не может видеть x?

Давайте рассмотрим ваш код:

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

Есть ли у нас способ получить старое значение или он "просочился" из нашего представления? Ожидается, что OS сообщит, когда закончите с malloc ed памятью, вызвав free(variable);.

Требуется ли старое значение для генерации нового значения? Как это может быть, когда strdup не может видеть переменную?

FYI, вот пример того, как можно реализовать strdup:

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

    strcpy(duplicate, original);
    return duplicate;
}

Ответ 4

По мере того как он в настоящее время стоит, вы всегда просачиваетесь от 4 до 8 байтов (в зависимости от вашей архитектуры). Независимо от strdup, который выделит требуемую динамическую память самостоятельно, вы переназначаете единственную переменную, содержащую указатель на вашу недавно выделенную область памяти.

Просто скажите

char* const variable = strdup(word);