libpq错误消息解除分配
libpq error message deallocation
下面是一个愚蠢的问题。libpq
的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
结构上的操作之间保持不变。
正如文档所说,不要期望它的内容保持不变,只需将它们保存在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*,让你知道只分配了这么多存储位置,如果你取消了末尾,混乱就会随之而来。
当然,这个函数可能从静态表返回数据,在这种情况下,既不应该写入也不应该删除它。同样,当你使用普通的旧指针时,没有办法知道。
- 指针会被解除分配吗?
- 基于浅树的数据结构的内存分配器,用于频繁分配和解除分配
- 解除分配矩形 2D 数组会根据尺寸产生错误
- 为什么在正确解除分配内存时出现内存泄漏?
- 堆栈变量超出范围时是否解除分配?
- 如何在不使用 "new" 关键字的情况下解除分配创建的对象的内存?
- 在 QStandardItemModel 中解除分配项目
- 解除分配此特定 2D 阵列的内存
- C++删除数组只会解除分配第一项
- 在 c++ 中使用向量解除分配
- 与解除分配堆数组相关的语法混淆
- 解除分配与 C++ 中的结构关联的所有内存
- 是否随作用域分配和解除分配堆栈帧
- 如果我使用 std::function 来捕获 lambda,我应该担心它被解除分配吗?
- 如果清除了 std::map 是否确保内存被解除分配
- 在另一个结构中的结构内解除分配指针
- 由 strcpy 设置的解除分配字符 * 时内存泄漏?
- 自定义内存分配和多个继承类的解除分配
- libpq错误消息解除分配
- cpputest错误消息分配/解除分配