Присвоить указателю символа значение NULL после использования в функции

#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 является членом этой структуры.