преобразование char** в char* или char
Вопрос
У меня есть старая программа, в которой используется некоторая библиотечная функция, но у меня нет этой библиотеки.
Итак, я пишу эту программу, используя библиотеки c ++.В этом старом коде есть какая-то функция, которая вызывается следующим образом
*string = newstrdup("Какая-то строка идет сюда");
строковая переменная объявляется как char **string;
Что он может делать в этой функции с именем "newstrdup"?Я много чего перепробовал , но я не знаю , что он делает ...Кто-нибудь может помочь
Решение
должна быть причина, по которой они написали "новую" версию strdup.Таким образом, должен быть угловой регистр, который он обрабатывает по-другому.например, возможно, нулевая строка возвращает пустую строку.
ответ litb является заменой напряженный, но я бы подумал, что есть причина, по которой они сделали то, что они сделали.
Если вы хотите использовать strdup напрямую, используйте define, чтобы переименовать его, а не писать новый код.
Другие советы
Функция используется для создания копии c-строк.Это часто необходимо для получения доступной для записи версии строкового литерала.Они (строковые литералы) сами по себе недоступны для записи, поэтому такая функция копирует их в выделенный буфер с возможностью записи.Затем вы можете передать их функциям, которые изменяют заданный ими аргумент, например strtok
который записывает в строку, которую он должен маркировать.
Я думаю, вы можете придумать что-то подобное, поскольку это называется новоенапряженный:
char * newstrdup(char const* str) {
char *c = new char[std::strlen(str) + 1];
std::strcpy(c, str);
return c;
}
Предполагается, что вы освободите его после выполнения с помощью строки, используя
delete[] *string;
Альтернативным способом его написания является использование malloc
.Если библиотека старая, возможно, она использовала ту, которую C ++ унаследовал от C:
char * newstrdup(char const* str) {
char *c = (char*) malloc(std::strlen(str) + 1);
if(c != NULL) {
std::strcpy(c, str);
}
return c;
}
Теперь вы должны освободить строку, используя free
когда закончите:
free(*string);
Предпочитайте первую версию, если вы пишете на C ++.Но если существующий код использует free
чтобы снова освободить память, используйте вторую версию.Остерегайтесь, что вторая версия вернет NULL
если нет доступной памяти для дублирования строки, в то время как первый выдает исключение в этом случае.Следует обратить внимание еще на одно обстоятельство, касающееся поведения, когда вы передаете NULL
аргумент к вашему newstrdup
.В зависимости от вашей библиотеки это может быть разрешено, а может и не быть разрешено.Поэтому при необходимости вставьте соответствующие проверки в вышеперечисленные функции.Существует функция, которая называется strdup
доступно в системах POSIX, но это не позволяет ни того, ни другого NULL
аргументы, а также не использует C++
оператор new для выделения памяти.
Во всяком случае, я поискал в Google codesearch newstrdup
функций найдено довольно много.Возможно, ваша библиотека входит в число результатов:
Линия *string = newstrdup("Some string goes here");
не проявляет никаких странностей по отношению к newstrdup
.Если string
имеет тип char **
тогда newstrdup
просто возвращается char *
как и ожидалось.Предположительно string
уже было установлено значение, указывающее на переменную типа char *
в который должен быть помещен результат.В противном случае код записывается через неинициализированный указатель..
newstrdup, вероятно, создает новую строку, которая является дубликатом переданной строки;он возвращает указатель на строку (которая сама по себе является указателем на символы).
Похоже, он написал функцию strdup() для работы с существующим указателем, вероятно, чтобы перераспределить его до нового размера, а затем заполнить его содержимым.Вероятно, он делает это, чтобы повторно использовать тот же указатель в цикле, где *string будет часто меняться, предотвращая утечку при каждом последующем вызове strdup().
Я бы, вероятно, реализовал это как string = redup(&string, "новое содержимое") ..но это всего лишь я.
Редактировать:
Вот фрагмент моей функции 'redup', которая может делать что-то похожее на то, что вы опубликовали, только по-другому:
int redup(char **s1, const char *s2)
{
size_t len, size;
if (s2 == NULL)
return -1;
len = strlen(s2);
size = len + 1;
*s1 = realloc(*s1, size);
if (*s1 == NULL)
return -1;
memset(*s1, 0, size);
memcpy(*s1, s2, len);
return len;
}
Конечно, мне, вероятно, следовало бы сохранить копию *s1 и восстановить ее, если realloc() завершится неудачей, но мне не нужно было впадать в паранойю.
Я думаю, вам нужно посмотреть, что происходит с переменной "string" внутри кода, поскольку прототип функции newstrdup(), по-видимому, идентичен версии библиотеки strdup().
Есть ли в коде какие-либо свободные вызовы (*string)?
Казалось бы, это странная вещь, если только она внутренне не сохраняет копию дублированной строки и снова не возвращает указатель обратно на ту же строку.
Опять же, я хотел бы спросить, почему?