简体   繁体   English

C-将结构的固定大小的向量转换为动态分配的

[英]C - Convert a fixed-size vector of a struct into dynamically allocated

In the following ANSI C code, how could I convert the vector conns[] from fixed-size into dynamically allocated (ie, perhaps by using malloc() and free() functions)? 在下面的ANSI C代码中,如何将向量conns[]从固定大小转换为动态分配的(即,也许通过使用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

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. 然后记得最后free(conns)

You don't need memset() as calloc() will already initialize the array with 0 s. 您不需要memset()因为calloc()已经用0 s初始化了数组。

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()失败,它们将自动设置,因此您可以在尝试使用连接之前进行检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM