#c #pointers #null #malloc
#c #указатели #null #malloc
Вопрос:
В C у меня есть функция, в которой я получаю строку в качестве параметра, а затем, после ее использования, я хочу ее уничтожить, потому что мне приходится вызывать ее в бесконечном цикле, и процесс возвращает -1073741819 (0xC0000005) через 5 минут.
Вот моя функция:
void renderText(char *text) {
//use it here and then destroy it.
*text = NULL; //not working!
text = NULL; //also not!
text[0] = ''; //also not!
}
Передача аргумента как:
renderText("Hello There!");
Я могу использовать
malloc()
функцию для создания строки, а затем могу перейти к вышеупомянутой функции, но мне приходится вызывать ее бесконечное количество раз, так что есть ли какой-либо способ обнулить ее в функции, поскольку указатели вызываются по ссылке.
Комментарии:
1. Нет, я не хочу использовать его обратно, только в
renderText()
, а затем уничтожить2. @Robert вы не можете
free
использовать строковый литерал в примере.3. @WeatherVane поскольку текст не выделяется динамически, я прав?
4. да, невозможно
free
что-то, что не выделяется динамически5. Да, лучше оставить задание вызывающему, который знает, что было передано в функцию. Пожалуйста, посмотрите последнее предложение моего ответа.
Ответ №1:
Эта строка
text[0] = '';
будет разыменовывать указатель text
, но вы уже
text = NULL;
так что это, вероятно, вызовет ошибку segfault. Вы можете
free(text);
но, вероятно, лучше позволить вызывающей стороне нести ответственность за это. Это делает функцию более полезной для аргумента, который не был выделен динамически или который вызывающий объект хочет использовать снова.
Однако ваше конкретное использование
renderText("Hello There!");
и строковый литерал не может быть изменен: он доступен только для чтения. Таким образом, ваша функция не должна пытаться уничтожить переданный аргумент.
Комментарии:
1. Я только что показал, что я выполнил три LOC, но я выполнил их один за другим.
Ответ №2:
Здесь
void renderText(char *text) { }
text
имеет char*
тип, и после его использования, чтобы не указывать text
на какую-либо недопустимую ячейку памяти, ее всегда лучше инициализировать с помощью NULL
, что означает, что она ни на что не указывает. Следовательно, это
text = NULL;
корректно только в этом API, поскольку оно не отражает NULL
присвоение в вызывающей функции, поскольку text
локально создается в этой функции. Это
*text = NULL;
недопустимо, поскольку *text
имеет char
тип, в то время как NULL
эквивалентно (void*)0
.
Это
text[0] = '';
Работает нормально, если обработка ошибок выполняется в соответствии с приведенным выше заявлением. Например
if(strlen(text) != 0) { /* something is there inside text */ }
Комментарии:
1.
text = NULL;
неверно . Он устанавливает только локальную копию того, что было передано.2. Я думаю, что лучшей версией
if(text[0] != '')
было быif(strlen(text) != 0)
или простоif(strlen(text))
3. @weatherVane Да, верно. Это нормально только в том API, которому
text
присвоенNULL
. В этом случае я бы предложил использоватьmemcpy()
. Например, после назначенияtext
дляNULL
выполнения,memcpy(arStruct->myString, text, strlen(text) 1);
предполагаяstruct
, что в качестве аргумента массив char является членом этой структуры.