2

ここで愚かな質問が来ます。libpqPQerrorMessage関数は a を返します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ドキュメントから

PQエラーメッセージ

接続の操作によって最後に生成されたエラー メッセージを返します。

char *PQerrorMessage(const PGconn *conn);

ほとんどすべての libpq 関数はPQerrorMessage、失敗した場合にメッセージを設定します。libpq の規則により、空でないPQerrorMessage結果は複数の行で構成され、末尾に改行が含まれることに注意してください。呼び出し元は結果を直接解放しないでください。PGconn関連付けられたハンドルが に渡されると解放されPQfinishます。PGconn結果の文字列は、構造に対する操作全体で同じままになるとは考えられません。

4

2 に答える 2

1

割り当てられたメモリへのプレーン オールド ポインタを返すライブラリ関数は、非常に古風で C っぽいものですが、まだ多くの関数が存在します。ライブラリ設計者の意図が、割り当てられたストレージの所有権をコードに譲渡することであったかどうかを知るには、ドキュメント以外に方法はありません。最新のライブラリ設計者は、shared_ptr<> を返して、ストレージの有効期間に関する意図を完全に明確にするか、文字列を std::string としてラップして、内部で割り当てと削除を処理することができます。

const char* 宣言は、ストレージの有効期間について実際には何も言いません。代わりに、ストレージを変更しないでください。割り当てられたストレージを返す古い学校の関数の場合、ストレージを削除することは変更することと同じではないことを知っておく必要があります。古い学校の関数は、 const char* を返して、非常に多くのストレージ位置しか割り当てられていないことを知らせたい場合があります。最後を書き留めると、混乱が生じます。

もちろん、この関数は静的テーブルからデータを返す可能性があります。その場合、書き込みも削除もすべきではありません。繰り返しますが、プレーン オールド ポインターを使用する場合、それを知る方法はありません。

于 2012-12-04T18:33:06.613 に答える