结构sqlite3的sqlite3c++正向声明导致析构函数中删除时出现无效指针错误
sqlite3 c++ forward declaration of struct sqlite3 leads to invalid pointer error on delete in destructor
在Linux上使用Eclipse CDT。以下是编译期间的代码和警告:
#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_ */
源
/*
* 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;
}
以及编译期间的警告
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;
这种方法与此人的做法非常相似http://www.dreamincode.net/forums/topic/122300-sqlite-in-c/
但我想确保释放数据库指针"struct-sqlite3"类成员
您的代码正试图发出delete _database;
,其中_database
的类型为sqlite3
。问题是编译器不知道sqlite3
是什么
您正向声明了sqlite3
是什么,但要发出delete
调用,需要编译了解sqlite3
的完整定义。您没有提供此类型的完整定义。
这来自sqlite3 API:https://www.sqlite.org/c3ref/close.html
sqlite3_close()和sqlite3_close_v2()例程是sqlite3对象的析构函数。如果sqlite3对象被成功销毁并且所有关联的资源都被释放,那么对sqlite3_close()和sqlite3_close_v2()的调用将返回SQLITE_OK。
相关文章:
- 析构函数删除错误的元素
- LinkedList removePosition 删除错误的元素
- 如何在为类创建 .h 和 .cpp 文件后删除错误?C++
- 使用C++类时出现巨大的删除错误
- C++解释此删除[]错误
- shared_ptr C++出现双重删除错误
- 如何删除错误:"." 标记之前的预期主表达式
- DoublyLinkedList删除错误
- 我使用构造函数(使用内存 Dinamic char *t = 新字符 [10] t = "test123456" ;))时遇到错误堆错误并在析构函数中删除 [] t;错误
- 分配字符串时出现 char* 新建和删除 [] 错误
- C++模板代码导致在显然未正确分配的对象上调用删除错误
- C++删除错误
- c++ STL删除错误
- 从二叉树中删除错误
- 矢量擦除函数删除错误的对象
- 二进制结构删除错误
- 如何从FLANNBASED匹配器在OPENCV中删除错误的匹配
- map删除错误的元素
- 使用 std::删除删除错误的字符
- c++ pair删除错误