1

当我使用 pqxx 创建到 psql 数据库的连接数组时,连接创建成功并且它们在数组中。但是当我要使用一个连接时,它会给我以下错误。我创建数组的方式也在下面提到。谁能告诉我这是什么原因。

for(int i=0;i<10;i++)
    {

        connection c("dbname=test user=postgres password=abc123\
                     hostaddr=127.0.0.1 port=5432");
        conList[i]=&c;
    }

  for (int j=0;j<10;j++)
        {
            cout<<conList[j]->is_open()<<endl; // this returns 0
        }

conList[0]->activate(); // at this point it gives the following error

在抛出“pqxx::broken_connection”实例后调用终止 what():与数据库的连接失败已中止

4

2 回答 2

2

connection c是在堆栈上创建的。当作用域关闭时(基本上,当}达到封闭时),编译器运行析构函数 for c. 连接将被关闭,不幸的是,您conList现在获取并存储的地址指向垃圾邮件。

解决此问题的简单方法是使用在堆上创建连接operator new,即

for (int i = 0; i < 10; i++) {
   conList[i] = new connection(/* args... */);
}

在某些时候,当您完成连接后,您将需要一个匹配的删除功能:

for (int  i = 0; i < 10; i++) {
    delete conList[i];
}

这很好,但如果你能提供帮助,最好避免使用C 风格的原始指针,原因有几个。更好的解决方案是将连接指针存储在 C++智能指针中。这将在正确的时间自动删除连接。

typedef std::shared_ptr<pqxx::connection> connection_ptr;
std::vector<connection_ptr> conList;

for (int i = 0; i < 10; i++) {
    conList.push_back(std::make_shared<pqxx::connection>(/* args... */));
}

现在,当 conList 被销毁时,您的所有连接都将自动关闭。

(如果您使用的是 C++11,std::unique_ptr可能会比共享指针更好。)

于 2013-10-22T09:45:16.960 回答
1

您正在存储局部变量c的地址conList,在第一次for循环之后,这些局部变量被释放,仅conList存储悬空指针,对悬空指针的调用函数调用具有未定义的行为

for(int i=0;i<10;i++)
{

    connection c("dbname=test user=postgres password=abc123\
                 hostaddr=127.0.0.1 port=5432");
    conList[i]=&c;  // c is local variable
}   // c is released here

for (int j=0;j<10;j++)
{
    cout<<conList[j]->is_open()<<endl;  // undefined behavior
}

conList[0]->activate(); // undefined behavior

考虑以下变化?

存储值而不是指针conList

for(int i=0;i<10;i++)
{

    connection c("dbname=test user=postgres password=abc123\
                 hostaddr=127.0.0.1 port=5432");
    conList[i] = c;  // make a copy of c
}   

for (int j=0;j<10;j++)
{
    cout<<conList[j].is_open()<<endl;  
}

conList[0].activate(); 
于 2013-10-22T09:30:16.597 回答