简体   繁体   English

无法释放由Malloc分配的内存

[英]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. 数据库第三列包含BLOB格式的值。 So the call to this database is to extract all columns between start and end time. 因此,对该数据库的调用是提取开始时间和结束时间之间的所有列。 I am using malloc 我正在使用malloc

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

to reserve memory for the values bcoz one time can have multiple values. 为值bcoz保留内存一次可以有多个值。 Now if I use: 现在,如果我使用:

free(valueBlobData)

the list historyRows does not contain any values. 列表historyRows不包含任何值。 However if I do not freememory, then I receive values in the stl list. 但是,如果我没有空闲内存,那么我会在stl列表中收到值。 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. 实际上,您正在尝试将historyRows悬挂指针悬空。 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 ). 释放内存并不意味着“ 清除 ”内存,当您释放内存时,它仅可用于其他分配,但是内存可能仍包含与调用free之前相同的内容( 或某些损坏的版本,这取决于方式)。分配器已实现 )。

Trying to inspect ( dereference ) a pointer that has been passed to free() is undefined behavior. 尝试检查( 取消引用 )已传递给free()的指针是未定义的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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