libpq错误消息解除分配

libpq error message deallocation

本文关键字:解除分配 消息 错误 libpq      更新时间:2023-10-16

下面是一个愚蠢的问题。libpqPQerrorMessage函数返回一个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结构上的操作之间保持不变。

正如文档所说,不要期望它的内容保持不变,只需将它们保存在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;

一个返回一个指向已分配内存的普通旧指针的库函数是非常老派和C-ish的,但仍然有很多。除了文档之外,没有其他方法可以知道库设计器的意图是否是将分配的存储的所有权转移到代码中。现代库设计器可以返回shared_ptr<>以使他们对存储寿命的意图完全清楚,或者将字符串封装为std::字符串,该字符串还处理隐藏的分配和删除。

constchar*声明并没有真正说明存储寿命。相反,它说不要修改存储。对于一个返回已分配存储的老派函数,你只需要知道删除存储和修改存储是不一样的。老派函数可能想返回一个const char*,让你知道只分配了这么多存储位置,如果你取消了末尾,混乱就会随之而来。

当然,这个函数可能从静态表返回数据,在这种情况下,既不应该写入也不应该删除它。同样,当你使用普通的旧指针时,没有办法知道。