SQLiteCpp icon indicating copy to clipboard operation
SQLiteCpp copied to clipboard

getFilename() -Error

Open DuanZhaobing opened this issue 2 years ago • 9 comments

SQLite::Database dbs("hello.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); auto db_name = dbs.getFilename().c_str(); When I use the above code to create and get the database file name, the compiler prompts an error and cannot get the relevant value<Error reading characters of string.>. https://github.com/SRombauts/SQLiteCpp/blob/164a606004b53bfdbb102e04adce038f04030a29/include/SQLiteCpp/Database.h#L465

DuanZhaobing avatar Aug 16 '23 06:08 DuanZhaobing

Error reading characters of string.

DuanZhaobing avatar Aug 16 '23 07:08 DuanZhaobing

please provide the following information:

  • compiler name
  • compiler version
  • OS
  • build system: cmake, meson, etc.

UnixY2K avatar Aug 17 '23 04:08 UnixY2K

Thank you for your information. The compiler name and version are "Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.5.5". OS-Microsoft Windows 10 Professional, Version-10.0.19045 Build System : MSBuild

I was building the project with Qt in Visual Studio(Using qt plugin). The following is the code block

void (CANDeviceInit:: * ptr_data_signal_2)(const std::vector<ZCANDataObj> &receive_data, UINT length) = &CANDeviceInit::CANDataSignal;
void (CenterWidget:: * ptr_data_receive_2)(const std::vector<ZCANDataObj> &receive_data, UINT length) = &CenterWidget::ReceiveCANData;
connect(this->dev, ptr_data_signal_2, this, ptr_data_receive_2);

void CenterWidget::ReceiveCANData(const std::vector<ZCANDataObj>& receive_data, UINT length)
{
std::string database_name = "database";
std::string table_name = "table_name";
SaveToDatabase(database_name, table_name, receive_data, length);
}

void CenterWidget::SaveToDatabase(
const std::string database_name,
const std::string table_name,
const std::vector<ZCANDataObj>& receive_data,
UINT length)
try {
// Open a database file in create/write mode
SQLite::Database database((database_name + ".db3").c_str(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);  // Error reading characters string
LOG(INFO) << "SQLite database file '" << database.getFilename().c_str() << "' opened successfully\n";  

// Execute SQL statements created by tables
const std::string kCreatTable = "CREATE TABLE IF NOT EXISTS "
+ table_name
+ "(Timestamp INTEGER PRIMARY KEY, Direction TEXT, ID TEXT, Length INTEGER, Data TEXT)";
database.exec(kCreatTable.data());
}
}

Please let me know what you think.

Best Regards

From: Jonathan Guzmán Date: 2023-08-17 12:43 To: SRombauts/SQLiteCpp CC: DuanZhaobing; Author Subject: Re: [SRombauts/SQLiteCpp] getFilename() -Error (Issue #437) please provide the following information: compiler name compiler version OS build system: cmake, meson, etc. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

DuanZhaobing avatar Aug 17 '23 06:08 DuanZhaobing

Hello,

I don't see anything wrong with how you use SQLiteCpp, only minor improvements that could be made to your code. I can imagine that the issue is with the rest of the program; I would bet for garbage memory (eg if CenterWidget object is already destroyed when the function is called).

I copy pasted and slightly adapted your code to run in the example1/main.cpp, it's working as expected.

#include <vector>

void SaveToDatabase(
    const std::string database_name,
    const std::string table_name,
    const std::vector<uint8_t>& receive_data,
    std::uint32_t length)
{
    try
    {
        // Open a database file in create/write mode
        SQLite::Database database((database_name + ".db3").c_str(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);  // Error reading characters string
        std::cout << "SQLite database file '" << database.getFilename().c_str() << "' opened successfully\n";
    }
    catch (std::exception& e)
    {
        std::cout << "SQLite exception: " << e.what() << std::endl;
    }
}

void ReceiveCANData(const std::vector<uint8_t>& receive_data, uint32_t length)
{
    std::string database_name("C:\\UnitySrc\\SQLiteCpp\\examples\\example1\\example");
    std::string table_name = "table_name";
    SaveToDatabase(database_name, table_name, receive_data, length);
}

int main()
{
    const std::vector<uint8_t> receive_data = { 0x01, 0x02, 0x03, 0x04 };
    ReceiveCANData(receive_data, receive_data.size());

The output starts with the expected log:

SQLite database file 'C:\UnitySrc\SQLiteCpp\examples\example1\example.db3' opened successfully

SRombauts avatar Aug 17 '23 09:08 SRombauts

Hello sir.

I used the same code in Visual Studio to create a new C++ Console App and a Qt Empty App, but with different results. In the C++ Console App, everything works. But in the Qt Empty App, the exception unable to open database file is thrown.

I don't have enough experience to look further into the cause. And I don't know if it's a problem with my usage or something else. Sincerely look forward to your reply.

//  In the Qt Empty App, no exception is thrown(when i use .data() or .c_str() function), but the database file name cannot be obtained(Unable to read memory).
SQLite::Database  new_db(s.data(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);  
#define SQLITECPP_COMPILE_DLL
#include <string>
#include <iostream>
#include <SQLiteCpp/SQLiteCpp.h>
#include <SQLiteCpp/VariadicBind.h>
int main()
{
	std::string s = "d.db3";
	try {
        // In the C++  Console App, everything works. But in the Qt Empty App, the exception unable to open database file is thrown.
	SQLite::Database  new_db(s, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);  
        
	// SQLite::Database  new_db(s.data(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);  //  In the Qt Empty App, no exception is thrown, but the database file name cannot be obtained(Unable to read memory).
	}
	catch (std::exception& e) {
		std::cout << "SQLite exception: " << e.what() << std::endl;
		return EXIT_FAILURE; // unexpected error : exit the example program
	}
	return 0;
}

getFilename

DuanZhaobing avatar Aug 18 '23 02:08 DuanZhaobing

can you upload a sample repo with the code that throws the error? as for the error seems that there is a use after free somewhere, probably related to the string used to initialize the database

UnixY2K avatar Aug 19 '23 00:08 UnixY2K

Hello Sir. The attachment is a simple sample code.Please check. Here is the git repository address. https://github.com/DuanZhaobing/SQLiteCpp_getFilename-test SQLiteCpp_getFilename-test.zip

DuanZhaobing avatar Aug 19 '23 04:08 DuanZhaobing

seems that it could be caused for the following reasons:

  • somewhere in your code the string is modified and you try to use the c_str after it, if you have a std::string is preferred to use it directly
  • the string is not utf8 encoded, the most easy solution in c++17 would be to use std::filesystem the constructor should convert it to utf8 automatically for you

for the example repo is recommended that you also show the example of your QT app, or at least a minimal failing example that we can debug

UnixY2K avatar Aug 21 '23 23:08 UnixY2K

Sorry to have kept you waiting, Sir. The project files of the Qt app have been uploaded to the git repository. https://github.com/DuanZhaobing/SQLiteCpp_getFilename-test/tree/main/SQLiteCppTest_Qt

DuanZhaobing avatar Sep 01 '23 06:09 DuanZhaobing