简体   繁体   English

sqlite3 c ++ struct的前向声明sqlite3在析构函数中删除时导致无效的指针错误

[英]sqlite3 c++ forward declaration of struct sqlite3 leads to invalid pointer error on delete in destructor

Using Eclipse CDT on Linux. 在Linux上使用Eclipse CDT。 Here is the code and the warnings during compile: 这是编译期间的代码和警告:

 #ifndef DATABASECONNECTION_HPP_
#define DATABASECONNECTION_HPP_

#include <sqlite3.h>
#include <string>

using namespace std;

class DatabaseConnection
{
private:
    sqlite3 *_database;
public:
    // constructors
    DatabaseConnection(const string &databaseURI, char mode='w');

    // destructor
    ~DatabaseConnection();
};

#endif /* DATABASECONNECTION_HPP_ */

the source 来源

/*
 * DatabaseConnection.cpp
 *
 *  Created on: Mar 31, 2015
 *      Author: Michael Wilson (mnw380@gmail.com)
 */

#include <DatabaseConnection.hpp>
#include <Exception.hpp>
#include <sqlite3.h>
#include <stdlib.h>
#include <sstream>
#include <FormattedString.hpp>
#include <FileUtils.hpp>

using namespace std;

DatabaseConnection::DatabaseConnection(const string &databaseURI, char mode)
{

   if (mode != 'w' && mode != 'r')
        throw Exception("Exception DatabaseConnection::DatabaseConnection. Mode must be \'r\' or \'w\' for read/write connection mode");

    int flags = (mode == 'w') ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;

    // this enables opening databases using URI
    flags |= SQLITE_OPEN_URI;

    // verify the database URI is formed correctly
    if ( !FormattedString::isFormatted(databaseURI, "file:/.*") && !FormattedString::isFormatted(databaseURI, "http:/.*") ) {
        // if not formed using standard URI syntax, then assume a file path and verify it exists
        if ( !FileUtils::Exists(databaseURI) )
            throw Exception("Exception DatabaseConnection::DatabaseConnection. File does not exist: " + databaseURI);
    }


    // returns non-zero on open error
    if ( sqlite3_open_v2(databaseURI.c_str(), &_database, flags, NULL) ) {
        ostringstream ss;
        ss << "Exception DatabaseConnection::DatabaseConnection. Error opening database " << databaseURI;
        throw Exception(ss.str());
    }
}

DatabaseConnection::~DatabaseConnection()
{
    sqlite3_close(_database);
    delete _database;
}

and the warnings during compile 和编译期间的警告

g++ -I/opt/ros/indigo/include -I"/home/user/workspace/Project/include" -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++11 -MMD -MP -MF"src/DatabaseConnection.d" -MT"src/DatabaseConnection.d" -o "src/DatabaseConnection.o" "../src/DatabaseConnection.cpp"
../src/DatabaseConnection.cpp: In destructor ‘DatabaseConnection::~DatabaseConnection()’:
../src/DatabaseConnection.cpp:48:9: warning: possible problem detected in invocation of delete operator: [enabled by default]
  delete _database;
         ^
../src/DatabaseConnection.cpp:48:9: warning: invalid use of incomplete type ‘struct sqlite3’ [enabled by default]
In file included from /home/user/workspace/Project/include/DatabaseConnection.hpp:11:0,
                 from ../src/DatabaseConnection.cpp:8:
/usr/include/sqlite3.h:228:16: warning: forward declaration of ‘struct sqlite3’ [enabled by default]
 typedef struct sqlite3 sqlite3;
                ^
../src/DatabaseConnection.cpp:48:9: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
  delete _database;

The approach is very similar to what this person has done http://www.dreamincode.net/forums/topic/122300-sqlite-in-c/ 该方法与该人员所做的非常相似http://www.dreamincode.net/forums/topic/122300-sqlite-in-c/

But I want to make sure to free the database pointer 'struct sqlite3' class member 但是我要确保释放数据库指针'struct sqlite3'类成员

Your code is attempting to issue a delete _database; 您的代码正在尝试发布delete _database; , where _database has the type sqlite3 . ,其中_database的类型为sqlite3 The problem is that the compiler does not know what a sqlite3 is. 问题是编译器不知道什么是sqlite3

You forward declared what sqlite3 is, but to issue a delete call requires the compile to know the full definition of sqlite3 . 您向前声明了sqlite3是什么,但是要发出delete调用,需要编译器知道sqlite3完整定义。 You did not supply the full definition of this type. 您没有提供此类型的完整定义。

This is from the sqlite3 API: https://www.sqlite.org/c3ref/close.html 这来自sqlite3 API: https//www.sqlite.org/c3ref/close.html

The sqlite3_close() and sqlite3_close_v2() routines are destructors for the sqlite3 object. sqlite3_close()和sqlite3_close_v2()例程是sqlite3对象的析构函数。 Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if the sqlite3 object is successfully destroyed and all associated resources are deallocated. 如果sqlite3对象成功销毁并且所有关联资源都已释放,则调用sqlite3_close()和sqlite3_close_v2()会返回SQLITE_OK。

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

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