освобождение сообщения об ошибке libpq

Здесь возникает глупый вопрос. libpq«s PQerrorMessage функция возвращает char const*

char const* msg = PQerrorMessage(conn);

Теперь, так как это constЯ не думаю, что мне следует это освобождать, и я никогда не видел, чтобы это было сделано ни в каких примерах. Но тогда, когда и как он освобождается?
Как он мог знать, когда я закончил использовать мой msg указатель?

Сначала я думал, что он освобождается после запроса другого сообщения об ошибке, но это не так.

// cause some error
char const* msg1 = PQerrorMessage(pgconn);

// cause another error
char const* msg2 = PQerrorMessage(pgconn);

// still works
std::cout << msg1 << msg2 << std::endl;

Может кто-нибудь пролить свет на это для меня?

Редактировать: кредиты Дмитрию Игришину

я спросил это в списке рассылки postgresql и оказалось, что мое первоначальное предположение было верным.
msg1 указатель не должен был быть действительным, и мне как-то повезло.

Редактировать: из документов postgresql

PQerrorMessage

Возвращает сообщение об ошибке, которое было сгенерировано последней операцией соединения.

char *PQerrorMessage(const PGconn *conn);

Почти все функции libpq установят сообщение для PQerrorMessage если они потерпят неудачу. Обратите внимание, что по соглашению libpq непустой PQerrorMessage результат может состоять из нескольких строк и включать в себя завершающий символ новой строки. Звонящий не должен освобождать результат напрямую. Он будет освобожден, когда связанный PGconn ручка передается PQfinish, Не следует ожидать, что результирующая строка останется неизменной при операциях на PGconn состав.

1

Решение

Библиотечная функция, которая возвращает простой старый указатель на выделенную память, очень старая и C-ish, но их все еще много. Нет другого способа, кроме документации, узнать, что разработчик библиотеки намеревался передать право собственности на выделенное хранилище вашему коду. Современный дизайнер библиотеки может вернуть shared_ptr<> чтобы сделать их намерение относительно срока хранения полностью ясным, или оберните строку в std :: string, которая также обрабатывает размещение и удаление под крышками.

Объявление const char * ничего не говорит о сроке хранения. Вместо этого говорится, что не изменяйте хранилище. Для функции старой школы, которая возвращает выделенное хранилище, вы просто должны знать, что удаление хранилища — это не то же самое, что его изменение. Функция старой школы может захотеть вернуть const char *, чтобы вы знали, что выделено только столько позиций памяти, и если вы запишете конец, то наступит хаос.

Конечно, эта функция может возвращать данные из статической таблицы, и в этом случае вы не должны ни записывать, ни удалять ее. Опять же, когда вы используете обычные старые указатели, нет способа узнать.

1

Другие решения

Делайте, как говорят документы, не ожидайте, что его содержимое останется постоянным, просто сохраните их в std::string вместо того, чтобы хранить указатель.

// cause some error
std::string msg1 = PQerrorMessage(pgconn);

// cause another error
std::string msg2 = PQerrorMessage(pgconn);

// works all the time
std::cout << msg1 << msg2 << std::endl;
2

По вопросам рекламы [email protected]