[英]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.