In the following ANSI C code, how could I convert the vector conns[]
from fixed-size into dynamically allocated (i.e., perhaps by using malloc()
and free()
functions)?
在下面的ANSI C代码中,我如何将vector conns []从fixed-size转换为动态分配(即,可能通过使用malloc()和free()函数)?
#include <stdio.h>
#include <string.h>
#include "libpq-fe.h"
#define MAX_DATABASES 20
int main(int argc, char **argv)
{
PGconn *conns[MAX_DATABASES]; // fixed-size vector
int i, ndbs;
ndbs = 3; // this value may vary
memset(conns, 0, sizeof(conns));
// instantiate connections
for (i = 0; i < ndbs; i++) {
conns[i] = PQconnectdb("dbname=template1");
}
// release connections
for (i = 0; i < ndbs; i++) {
fprintf(stdout, "%d) %p\n", i + 1, conns[i]);
if (conns[i])
PQfinish(conns[i]);
conns[i] = NULL;
}
return 0;
}
The PGconn
type is actually a typedef struct imported from /src/interfaces/libpq/libpq-fe.h
:
PGconn类型实际上是从/src/interfaces/libpq/libpq-fe.h导入的typedef结构:
typedef struct pg_conn PGconn;
The pg_conn
is a struct found in /src/interfaces/libpq/libpq-int.h
:
pg_conn是/src/interfaces/libpq/libpq-int.h中的结构:
struct pg_conn
{
char *pghost;
char *pghostaddr;
char *pgport;
char *pgunixsocket;
...
};
The code above works successfully, despite being fixed-size. It can be compiled with the following instruction (PostgreSQL sources needed):
上面的代码成功运行,尽管是固定大小的。它可以使用以下指令编译(需要PostgreSQL源代码):
gcc -I/usr/src/postgresql-9.3/src/interfaces/libpq -I/usr/src/postgresql-9.3/src/include pqc.c -L/usr/src/postgresql-9.3/src/interfaces/libpq -lpq -lpthread -o pqc
2 个解决方案
#1
1
You can do it like this
你可以这样做
PGconn **connections;
size_t number_of_connections;
number_of_connections = 10; // Do not exceed max_connections
// from postgresql.conf
// (default 100)
connections = malloc(number_of_connections * sizeof(*connections));
if (connections == NULL)
return -1; // Allocation error, cannot continue
for (size_t i = 0 ; i < number_of_connections ; ++i)
connections[i] = PQconnectdb("dbname=template1");
// Do whatever you want with connections, and free
for (size_t i = 0 ; i < number_of_connections ; ++i)
PQfinish(connections[i]);
free(connections);
You don't need to set all the pointers to NULL
, they will automatically be set if PQconnectdb()
fails, so you can check that before trying to use the connection.
您不需要将所有指针都设置为NULL,如果PQconnectdb()失败,它们将自动设置,因此您可以在尝试使用连接之前检查它们。
#2
1
You don't have to change much, just use calloc
:
你不必改变太多,只需使用calloc:
PGconn** conns = calloc(MAX_DATABASES, sizeof(PGConn *));
and then remember to free(conns)
in the end.
然后记得最后释放(conns)。
You don't need memset()
as calloc()
will already initialize the array with 0
s.
你不需要memset(),因为calloc()已经用0s初始化数组。
#1
1
You can do it like this
你可以这样做
PGconn **connections;
size_t number_of_connections;
number_of_connections = 10; // Do not exceed max_connections
// from postgresql.conf
// (default 100)
connections = malloc(number_of_connections * sizeof(*connections));
if (connections == NULL)
return -1; // Allocation error, cannot continue
for (size_t i = 0 ; i < number_of_connections ; ++i)
connections[i] = PQconnectdb("dbname=template1");
// Do whatever you want with connections, and free
for (size_t i = 0 ; i < number_of_connections ; ++i)
PQfinish(connections[i]);
free(connections);
You don't need to set all the pointers to NULL
, they will automatically be set if PQconnectdb()
fails, so you can check that before trying to use the connection.
您不需要将所有指针都设置为NULL,如果PQconnectdb()失败,它们将自动设置,因此您可以在尝试使用连接之前检查它们。
#2
1
You don't have to change much, just use calloc
:
你不必改变太多,只需使用calloc:
PGconn** conns = calloc(MAX_DATABASES, sizeof(PGConn *));
and then remember to free(conns)
in the end.
然后记得最后释放(conns)。
You don't need memset()
as calloc()
will already initialize the array with 0
s.
你不需要memset(),因为calloc()已经用0s初始化数组。