简体   繁体   中英

Sqlite3 and pthread, double free or corruption (out)

I try to create a thread which connect to a database, takes some data from there and print to the console. The problem is that when that thread finish throw an exception:

double free or corruption (out) Aborted (core dumped)

I try to use sqlite3 and pthread and this two are not really friends.

I think, but I am not sure that the problems comes from the Database class.

Anyone have any idea what produce the exception? Here is my code: link

Database class:

class Database {
private:
  sqlite3 *db;
  static int CallBack(void *data, int argc, char **argv, char **azColName)
  {
    int index = 0;
    char** dataToReturn = new char*[1000];

    while (dataToReturn[index])
    {
        index++;
    }

    for (int i = index; i < argc + index; i++)
    {
        dataToReturn[i] = (char *)malloc(sizeof(char) * sizeof(argv[i - index]));
        strcpy((dataToReturn)[i], argv[i - index]);
    }

    return 0;
}

public:
  char **Select()
  {
    char *zErrMsg = 0;
    int rc;

    rc = sqlite3_open("test.db", &db);

    if (rc)
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(1);
    }
    else
    {
        fprintf(stderr, "Opened database successfully\n");
    }
    char **data;

    int rc2 = sqlite3_exec(db, "SELECT * FROM SHARED_FILE", CallBack, data, &zErrMsg);

    if (rc2 != SQLITE_OK)
    {
        sqlite3_free(zErrMsg);
        exit(2);
    }

    sqlite3_close(db);
    return data;
}

Thread functions:

static void FunctioForThread()
{
    printf("start");

    auto database = new Database();
    char** returnData = database->Select();

    printf("something from db: %s \n", returnData[0]);
    printf("stop");
}

static void *threadd(void *arg)
{
    pthread_detach(pthread_self());
    fflush(stdout);

    FunctioForThread();
}

And the main function:

int main()
{
    pthread_t thread;
    char arg[100] = "test";
    pthread_create(&thread, NULL, &threadd, arg);

    while(1);
}

You are dereferencing data passed to CallBack in ((char **)data)[index] , but its value was passed from data in Select through the callback of sqlite3_exec . data in Select was allocated for in:

char **data = (char **)malloc(0);

You are not allowed to dereference a pointer to a zero-length allocation. Also note that the behavior of a zero-size malloc is implementation-defined, so it should be avoided (as should malloc in C++ in preference of new anyway).


After edit:

Now data is returned from Select without ever writing to it, but is then dereferenced in

returnData[0]

in FunctioForThread . That is undefined behaior.

Furthermore sizeof(argv[i - index]) does not return the length of the string that argv[i - index] points to. It will return the size of the pointer type. Probably your allocations will therefore be too small, again undefined behavior. Use std::strlen to get the length of a zero-terminated string.

Then the pointer argv[i - index] may also be NULL to indicate a NULL value in the returned row (see documentation of sqlite3_exec ). In that case strcpy ing from it will also be undefined behavior.

The loop while (dataToReturn[index]) will cause undefined behavior because an array for dataToReturn was allocated, but its elements never set. Even if the values were set, note that the condition is satisfied if and only if the C-style string dataToReturn[index] points to has length zero. If such a string doesn't exist in the allocated range, again the behavior is undefined.


You also have memory leaks because you never free any of your malloc ed data and because dataToReturn is discarded at the end of each CallBack call, it is not very useful.


There is no good reason to use all these C-style constructs. Use new instead of malloc , std::string and std::vector instead of char arrays, std::cout and std::cerr instead of printf and fprintf(stcerr, ... , std::thread instead of pthreads . The only point were these things need to be considered is at the interface boundary to the C library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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