简体   繁体   中英

Not able to free memeory allocated by Malloc in

I have this below written code which when called extracts values from an internal database. The database 3rd colum contains value in BLOB format. So the call to this database is to extract all columns between start and end time. I am using malloc

unsigned char *valueBlobData = (unsigned char*)malloc(valueBlobSize);

to reserve memory for the values bcoz one time can have multiple values. Now if I use:

free(valueBlobData)

the list historyRows does not contain any values. However if I do not freememory, then I receive values in the stl list. But that results in memory leak.

The question is , am I freeing the memory at wrong position. If yes how can I make it work?

bool SQHISDB::getHisVArray(unsigned long startTime, unsigned long endTime,
    std::list<tHistoryRow> &historyRows)
{
    int rc;
    int counter = 0;
    tHistoryRow tempHistoryRow; // Struct having four variables
    unsigned int A1 =1, A2=2;
    const char *zSql = "SELECT * "
        "FROM node_values "
        "WHERE A1 = ? "
        "AND A2 = ? "
        "AND (sourceTS BETWEEN ? AND ? ) "
        ";";

    sqlite3_stmt *pStmt = NULL;

    rc = sqlite3_prepare_v2(this->db, zSql, std::strlen(zSql), &pStmt, NULL);

    if (rc != SQLITE_OK)
    {
        return rc;
    }

    sqlite3_bind_int(pStmt, 1, A1);
    sqlite3_bind_int(pStmt, 2, A2);
    sqlite3_bind_int64(pStmt, 3, startTime);
    sqlite3_bind_int64(pStmt, 4, endTime;

    while (sqlite3_step(pStmt) == SQLITE_ROW)
    {
        counter++;
        unsigned long sourceTimestamp = sqlite3_column_int64(pStmt, 4);
        unsigned int valueBlobSize = sqlite3_column_bytes(pStmt, 3);
        unsigned char *valueBlobData = (unsigned char*)malloc(valueBlobSize);

        std::memcpy(valueBlobData, sqlite3_column_blob(pStmt, SQLITE_HISTORYDB_INDEX_VALUE), valueBlobSize);

        tempHistoryRow.sourceTimestamp = sourceTS;
        tempHistoryRow.blobSize = valueBlobSize;
        tempHistoryRow.blob = valueBlobData;

        historyRows.push_back(tempHistoryRow);
        free(valueBlobData);
    }
    sqlite3_finalize(pStmt);

    return true;
}

Effectively you are trying to push to historyRows a dangling pointer. This is definitely wrong.

For me it looks like you want to use simple vector to manage this buffer.

struct tHistoryRow {
    std::vector<unsigned char> blob;
    … … …
};

bool SQHISDB::getHisVArray(unsigned long startTime, unsigned long endTime,
    std::list<tHistoryRow> &historyRows)
{
    int rc;
    int counter = 0;
    unsigned int A1 =1, A2=2;
    static const std::string zSql{ "SELECT * "
        "FROM node_values "
        "WHERE A1 = ? "
        "AND A2 = ? "
        "AND (sourceTS BETWEEN ? AND ? ) "
        ";"  };

    sqlite3_stmt *pStmt = NULL;

    rc = sqlite3_prepare_v2(this->db, zSql.data(), zSql.length(), &pStmt, NULL);

    if (rc != SQLITE_OK)
    {
        return rc;
    }

    sqlite3_bind_int(pStmt, 1, A1);
    sqlite3_bind_int(pStmt, 2, A2);
    sqlite3_bind_int64(pStmt, 3, startTime);
    sqlite3_bind_int64(pStmt, 4, endTime;

    while (sqlite3_step(pStmt) == SQLITE_ROW)
    {
        counter++;
        unsigned long sourceTimestamp = sqlite3_column_int64(pStmt, 4);
        unsigned int valueBlobSize = sqlite3_column_bytes(pStmt, 3);


        tHistoryRow tempHistoryRow; // it would be nice to provide constructor
        tempHistoryRow.blob.resize(valueBlobSize);
        auto pBlob = sqlite3_column_blob(pStmt, SQLITE_HISTORYDB_INDEX_VALUE);
        std::copy(pBlob, pBlob + valueBlobSize, tempHistoryRow.blob.begin());

        tempHistoryRow.sourceTimestamp = sourceTS;

        historyRows.push_back(std::move(tempHistoryRow));
    }
    sqlite3_finalize(pStmt);

    return true;
}

Freeing memory does not mean " clearing " memory, when you free memory it just becomes available for other allocations, but the memory might still contain the same contents as it did before calling free ( or some corrupted version of it, it depends on the way the allocator was implemented ).

Trying to inspect ( dereference ) a pointer that has been passed to free() is undefined behavior.

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