Рейтинг:
6
Richard MacCutchan
Документация (которую вы всегда должны проверять в первую очередь) : gai_strerror[^] говорит вам, что возврат является указателем на символьную константу, поэтому вы ничего не должны с ней делать.
[no name]
Почему же она, будучи const char*
то есть ты не должен ничего с ним делать? Я пытаюсь понять причины, по которым эти вещи таковы, каковы они есть.
Richard MacCutchan
Потому что вещь, на которую указывают, - это постоянный иначе говоря , он не может быть изменен. И вы не можете создать константу с помощью new
или malloc
, так как динамически создаваемое пространство памяти всегда может быть изменено.
[no name]
Итак, указатели const никогда не нужно удалять ни в одном сценарии?
Richard MacCutchan
И еще один вопрос, с которым нужно быть осторожным. Вы не должны приводить этот указатель к простому char*
, поскольку вы отбрасываете его постоянство, тем самым оставляя его открытым для неправильного использования.
CPallini
Это не совсем так. Пример (по общему признанию, надуманный) :
#include <stdlib.h>
#include <stdio.h>
static char * p = (char *)0;
void init_library();
const char * get_const_string();
void terminate_library();
void init_library()
{
if ( ! p )
{
p = (char * ) malloc(6);
p[0]='h'; p[1]='e'; p[2] = 'l'; p[3] = 'l'; p[4] = 'o'; p[5] = '\0';
}
}
void terminate_library()
{
if ( p ) free (p);
}
const char * get_const_string()
{
return p;
}
Richard MacCutchan
Ну, вы можете придумать все, что угодно, если очень постараетесь.
CPallini
Действительно. Однако пример кода надуман, а не суть. Мы обычно думаем а const char * указатель обращается к памяти только для чтения, но это не всегда верно.
Richard MacCutchan
Я полностью согласен, но я намеренно избегал этого момента, чтобы попытаться сохранить вещи простыми.
Richard MacCutchan
И конечно же компилятор поймает следующее:
const char *s = get_const_string();
s[0] = 'B';
// and ...
const char *s = get_const_string();
free (s);
CPallini
Однако это не меняет дела: вы не можете предположить, как на самом деле распределяется строка.
Richard MacCutchan
Нет, но весь смысл заключается в том, что const
квалификатор должен помочь вам избежать неосторожных ошибок. Если вы злоупотребляете им, то вы несете ответственность за любые проблемы.
Rick York
Утверждать: "вы не должны ничего с этим делать" - совершенно неверно. Вы можете распечатать его, скопировать и многое другое. Единственное, что вы не можете сделать, это изменить его, потому что это "const." Освобождение или удаление означало бы его изменение, поэтому они не допускаются.
Кроме того, как указано в другом месте, он также не должен быть приведен к непостоянному значению. Для этого есть несколько причин, но одна из них заключается в том, что большинство строковых классов принимают строки символов const, но не неконстантные, так что в вашем случае это не подходит. Я упомянул об этом, потому что в вашем коде есть "consoleHelper.write_status("Error: " + cast_ch")", который выглядит так, как будто вы используете оператор + из класса string для добавления строк, и обычно это не будет работать, если оба аргумента не являются "const char *" или строковыми объектами.
Richard MacCutchan
Я отвечал в контексте того, можно ли использовать free или delete для такого указателя. Другие виды использования идут без слов. И это я сказал, чтобы ты не бросал Конста.
Рейтинг:
19
CPallini
Вы не должны освобождать память (она явно не требуется в документации, и, кроме того, вы не знаете, как библиотека на самом деле выделяет ее).
Пожалуйста, обратите внимание: если есть утечка, то это (маловероятная) ошибка автора библиотеки (и, вероятно, безвредная). С другой стороны, вызов delete для указателя был бы опасен и полностью лежал бы на вашей ответственности. :-)
[no name]
О какой библиотеке вы говорите? Какая документация? Код, стоящий за приведением, не может сказать, когда он закончит использоваться, поэтому он не может освободить саму память, конечно же?
CPallini
Библиотека, реализующая gai_strerror функция. Документация такой библиотеки. Если вы не знаете, как выделяется память (и какая среда выполнения C выделила ее), вы не должны ее освобождать.
[no name]
Весь код, кроме gai_strerror, является моим собственным.
CPallini
Строка приходит только из gai_strerror.
Давайте посмотрим правде в глаза: попытка освободить память на таком указателе-это явная ошибка.
[no name]
Но я хочу понять причину *почему*.
CPallini
Тогда вы должны учиться. Отправной точкой могла бы стать эта статья:
https://blogs.msdn.microsoft.com/oldnewthing/20060915-04/?p=29723