1

メインプログラムでPQconnectdbを呼び出すと、すべて非常にうまく動作しますが、関数内で呼び出すと、セグメンテーション違反が発生します。ここで実行されるコード

#include <stdio.h>
#include <stdlib.h>
#include <postgresql/libpq-fe.h>



#define PG_HOST    "127.0.0.1"
#define PG_USER    "postgres"
#define PG_DB      "postgres"
#define PG_PASS    "postgres"
#define PG_PORT    5432



static void
exit_nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}


int main( void )

{

char       conninfo[250];
PGconn     *conn = NULL;
PGresult   *pgres = NULL;

sprintf(conninfo, "user=%s password=%s dbname=%s hostaddr=%s port=%d", PG_USER, PG_PASS, PG_DB, PG_HOST, PG_PORT);
conn = PQconnectdb(conninfo);

if (PQstatus(conn) != CONNECTION_OK)
{
    fprintf(stderr, "ERROR: Connection to database failed: %s", PQerrorMessage(conn));
    exit_nicely(conn);
}


PQfinish(conn);

return 0;
}

このコードは非常にうまく実行されます。

しかし、関数内にPQconnectを配置すると、プログラムはセグメンテーション違反を生成します

int connect(char* conninfo, PGconn* conn)
{

conn = PQconnectdb(conninfo);

if (PQstatus(conn) != CONNECTION_OK)
{
    fprintf(stderr, "ERROR: Connection to database failed: %s", PQerrorMessage(conn));
    exit_nicely(conn);
}

return 1;
}




int main( void )

{

char       conninfo[250];
PGconn     *conn = NULL;
PGresult   *pgres = NULL;

sprintf(conninfo, "user=%s password=%s dbname=%s hostaddr=%s port=%d", PG_USER, PG_PASS, PG_DB, PG_HOST, PG_PORT);

connect(conninfo, conn);
if(!conn)
 fprintf(stderr, "conn is null.\n");


PQfinish(conn);

return 0;

}

ここでクラッシュスタック

(gdb) where
#0  __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32
#1  0x00007ffff7893086 in __GI___strdup (s=0x7 <Address 0x7 out of bounds>) at strdup.c:42
#2  0x00007ffff7bbbd87 in ?? () from /usr/lib/libpq.so.5
#3  0x00007ffff7bbc2a5 in ?? () from /usr/lib/libpq.so.5
#4  0x00007ffff7bbe389 in PQconnectStart () from /usr/lib/libpq.so.5
#5  0x00007ffff7bbe416 in PQconnectdb () from /usr/lib/libpq.so.5
#6  0x0000000000400912 in connect (conninfo=0x7 <Address 0x7 out of bounds>, conn=0x60a630) at pqconnect.c:25
#7  0x00007ffff7bbcadb in PQconnectPoll () from /usr/lib/libpq.so.5
#8  0x00007ffff7bbd77e in ?? () from /usr/lib/libpq.so.5
#9  0x00007ffff7bbe3b4 in PQconnectStart () from /usr/lib/libpq.so.5
#10 0x00007ffff7bbe416 in PQconnectdb () from /usr/lib/libpq.so.5
#11 0x0000000000400912 in connect (conninfo=0x7fffffffe600 "user=btel_user password=JwN5K9e18PsTb dbname=ULIC hostaddr=127.0.0.1 port=5432", conn=0x0) at pqconnect.c:25

#12 0x00000000004009e3 in main()at pqconnect.c:49

関数connectを静的として宣言すると、セグメンテーション違反エラーは発生しませんが、変数connに対して返されるポインターはNULLです。

なぜ?:(

4

2 に答える 2

2

connectあなたはあなたと標準ライブラリの間に取り違えがあると思いますconnect。あなたconnectが優先されるので、PQconnectdb電話をかけようとするとconnect事態は悪化します。
関数の名前を変更してみてください。
静的connectにすることで、混乱を防ぐこともできます。これは、クラッシュが解消される理由を説明しています。

また、connパラメータをconnect誤ってに渡します。値によって渡されるため、の変数mainは変更されず、そのまま残りますNULL
参照で渡す必要があります。

于 2012-06-26T09:28:54.353 に答える
0

注:@Aleix==>このコードは正常に実行されるはずです。

int pg_connect(char* conninfo, PGconn** conn)
{

    *conn = PQconnectdb(conninfo);
    if (PQstatus(*conn) != CONNECTION_OK) {
        fprintf(stderr,
                "ERROR: Connection to database failed: %s",
                PQerrorMessage(*conn));
        return 0;
    }

    return 1;
}

/* set correctely your values here */
#define PG_HOST    "127.0.0.1"
#define PG_USER    "postgres"
#define PG_DB      "postgres"
#define PG_PASS    "postgres"
#define PG_PORT    5432

int main(int argc, char *argv[])
{
    char        conninfo[250];
    PGconn     *conn  = NULL;
    PGresult   *pgres = NULL;

    sprintf(conninfo,
            "user=%s password=%s dbname=%s hostaddr=%s port=%d",
            PG_USER, PG_PASS, PG_DB, PG_HOST, PG_PORT);

    if (!pg_connect(conninfo, &conn)) {
        goto end;
    }


    /*
        Here fit your staff
     */


    end:
      PQfinish(conn);
      return 0;

}
于 2013-11-29T10:00:40.630 に答える