2

一个愚蠢的问题来了。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;

有人可以为我解释一下吗?

编辑:感谢 Dmitriy Igrishin

我在 postgresql 邮件列表上了这个问题,结果证明我最初的假设是正确的。指针不应该是有效
的,不知何故我很幸运。msg1

编辑:来自 postgresql 文档

PQerrorMessage

返回由对连接的操作最近生成的错误消息。

char *PQerrorMessage(const PGconn *conn);

几乎所有的 libpq 函数都会在PQerrorMessage失败时设置消息。请注意,按照 libpq 约定,非空PQerrorMessage结果可以由多行组成,并且将包括一个尾随换行符。调用者不应直接释放结果。PGconn当关联的句柄传递给时,它将被释放PQfinish。不应期望结果字符串在PGconn结构上的操作中保持相同。

4

2 回答 2

2

正如文档所说,不要期望它的内容保持不变,只需将它们保存在 a 中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;
于 2013-06-11T02:33:41.717 回答
1

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

const char* 声明并没有真正说明存储寿命。相反,它说不要修改存储。对于返回分配存储的老式函数,您只需要知道删除存储与修改存储不同。老派函数可能想要返回一个 const char* 来让您知道只分配了这么多存储位置,如果您注销最后,就会出现混乱。

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

于 2012-12-04T18:33:06.613 回答