簡體   English   中英

無法釋放由Malloc分配的內存

[英]Not able to free memeory allocated by Malloc in

我有下面這段編寫的代碼,該代碼在調用時從內部數據庫中提取值。 數據庫第三列包含BLOB格式的值。 因此,對該數據庫的調用是提取開始時間和結束時間之間的所有列。 我正在使用malloc

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

為值bcoz保留內存一次可以有多個值。 現在,如果我使用:

free(valueBlobData)

列表historyRows不包含任何值。 但是,如果我沒有空閑內存,那么我會在stl列表中收到值。 但這會導致內存泄漏。

問題是,我在錯誤的位置釋放了內存。 如果是,我如何使它工作?

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;
}

實際上,您正在嘗試將historyRows懸掛指針懸空。 這絕對是錯誤的。

對我來說,您似乎想使用簡單的向量來管理此緩沖區。

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;
}

釋放內存並不意味着“ 清除 ”內存,當您釋放內存時,它僅可用於其他分配,但是內存可能仍包含與調用free之前相同的內容( 或某些損壞的版本,這取決於方式)。分配器已實現 )。

嘗試檢查( 取消引用 )已傳遞給free()的指針是未定義的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM