[pgsql-jp: 35652] Re: libPQ の PQexec 関数がメモリリークで落ちます

堀越 horihorikoshi @ yahoo.co.jp
2005年 7月 4日 (月) 12:14:03 JST


堀越です。

下記サンプルをコンパイルして実行したところ、何も問題はな
かったですよ。だた一点修正した箇所があり、"#include
<vcl.h>"
の行をコメントアウトしました。

使用したコンパイラがC++Builderではなく、プリコンパイル
ヘッダは使えないのでコメントアウトしたのですが...。恐
らくコンパイラの不具合ではないでしょうか?

"#include <vcl.h>"の行をコメントアウトして、再度試してみ
てください。では!


--- 大西 義人 <yoshito @ noveluck.co.jp> からのメッセージ
:
> こんにちわ。大西です。
> 石井様、水野様にご指摘いただいた箇所を検証してみました
。
> 
> >>ところで「メモリリークが発生して」とありますが,そう
判断した根拠は何な
> >>んでしょうか?それを示せばもっとよいアドバイスを得ら
れるかも.
> 
> >>プログラムが即時に落ちるようなエラーなら、メモリリー
クよりも
> >>セグメント境界エラーとかNULL参照ではないかと思うので
すが
> >>違いますか?
> 
> メモリリークではないですね。
> 用語を間違っていました。すみません。
> 正確にはこのようなメッセージです。
> 
> ---------------------------
> デバッガ例外が発生
> ---------------------------
> プロジェクト Samplebpr.exe が EAccessViolation
> クラスの例外を生成しました。
> 'アドレス 326663F0 でアドレス F87206C0
> に対する読み込み違反がおきました。'
> プロセスは停止しています。再開するにはステップ実行また
は実行を選択してください。
> 
> 
> >>手元にソースを読める環境がないのできっちり追った訳で
は
> >>ないですが、PQexec関数自身はSQL文の構文解析なんて
> >>せずPostgreSQL本体に渡してるだけだと思います。
> 
> PQexec関数の中身はおっしゃる通りです。
> PQexec関数の内部で引き渡す直前の文字列をファイルに書き
出したのですが、
> 特に問題ありませんでした。(コピーしてPGAdmin実行すれ
ばSQLは走ります)
> 
> 
> >>自作Cアプリケーションがバグっている,に1票.
> 
> >>私としては自作PGのバグ説、もしくはlibpqのコンパイル
を
> >>失敗してる説に1票です
> 
> 使用しているソースは下記のものです。(ほとんどサンプル
そのまんまですが)
> ほぼ同じソースでVCでは問題なく動いたので、
> C++Builder用のDLL作成をするときの、
> コンパイル方法がまずいのでしょうか・・・
> 一応コンパイルし直してみたのですが、結果は同じでした。
> 
> 
>
//---------------------------------------------------------------------------
> 
> #include <vcl.h>
> #include <stdio.h>
> #include "libpq-fe.h"
> 
> #pragma hdrstop
> 
>
/*************************************************************************************
> ' 関数宣言
>
'*************************************************************************************/
> PGconn* DBconnect(char *conninfo);
> PGresult*  DBexec(PGconn *conn, char *command);
> 
>
//---------------------------------------------------------------------------
> 
> #pragma argsused
> int main(int argc, char* argv[])
> {
>     char		Conninfo[256+1];
>     char		ID[256+1];
>     char		PWD[256+1];
>     PGconn		*Conn;
>     PGresult	*Res;
> 
> 
>     // 初期化
>     memset(Conninfo,0,sizeof(Conninfo));
>     memset(ID ,0,sizeof(ID));
>     memset(PWD,0,sizeof(PWD));
>     strcpy(ID,"postgres");
>     strcpy(PWD,"postgres");
> 
> 
>     // DBの接続
>     sprintf(Conninfo, "host=localhost
> dbname=template1 user=%s password=%s",ID,PWD);
>     Conn = DBconnect(Conninfo);
> 
>     if (Conn == NULL){
>         return -1;
>     }
> 
>     Res = DBexec(Conn, "DROP DATABASE fscmsdb");
>     if ( Res != NULL ){
>          PQclear(Res);
>     }else{
>         return -1;
>     }
> 
>     Res = DBexec(Conn, "CREATE DATABASE fscmsdb
> TEMPLATE template0
>     ENCODING 'UTF-8'" );
>    if ( Res != NULL ){
>         PQclear(Res);
>    }else{
>         return -1;
>    }
> 
>    PQfinish(Conn);
> 
>    // DBの接続
>    sprintf(Conninfo, "host=localhost dbname=fscmsdb
> user=%s
>    password=%s",ID,PWD);
>    Conn = DBconnect(Conninfo);
>    if(Conn == NULL){
>        return -1;
>     }
> 
>     static char www[] = "create table hoge (id int,
> value int, txt TEXT,PRIMARY KEY(id));";
> 
>     //  ここでのPQexecで落ちる 
>     Res = DBexec(Conn, www);
>     if(Res != NULL ){
>        PQclear(Res);
>     }
>     PQfinish(Conn);
>     return 0;
> }
>
//---------------------------------------------------------------------------
> 
> 
>
/*************************************************************************************
> ' 関数名        :DBconnect
> ' 処理概要      :データベース接続
>
'*************************************************************************************/
> PGconn* DBconnect(char *conninfo)
> {
>     PGconn		*conn;
>     
> 	conn = PQconnectdb(conninfo);
> 
> 	if ( PQstatus(conn) != CONNECTION_OK ){
> 
> 		//sprintf(stderr, "DB connect failed: %s\n",
> PQerrorMessage(conn));
> 		PQfinish(conn);
> 		return NULL;
> 	}
>     
> 	return conn;
> }
> 
> 
>
/*************************************************************************************
> ' 関数名        :DBexec
> ' 処理概要      :データベースコマンド実行
>
'*************************************************************************************/
> PGresult*  DBexec(PGconn *conn, char *command)
> {
> 	PGresult	*res;
> 
> 	res = PQexec(conn, command);
> 
> 	if (PQresultStatus(res) != PGRES_COMMAND_OK){
> 		fprintf(stderr, "'%s' command failed: %s",
> command, PQerrorMessage(conn));
> 		PQclear(res);
> 		return NULL;
> 	}
> 
> 	return res;
> }
> 
> 



pgsql-jp メーリングリストの案内