Soru Libsql bellek sızıntısı hk.

  • Konuyu açan Konuyu açan zodiac160
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 6
  • Gösterim Gösterim 89
Herhangi bir konuda danışmak istediğiniz soru varsa bu öneki seçebilirsiniz.

zodiac160

MT Üye
MT Üye
Mesaj
180
Çözümler
9
Beğeni
75
Puan
479
Ticaret Puanı
0
Kaynak kodlarını inceliyordum bazı durumlar gözüme çarptı AsyncSQL.cpp içerisinde bazı yerlerde new kullanılmış fakat delete kullanılmamış olduğunu gördüm. Bu konu hakkında bilgisi olan var mı daha başka yerlerde delete edilmiş olabilir mi ?

Kod:
Genişlet Daralt Kopyala
void CAsyncSQL::AsyncQuery(const char * c_pszQuery)
{
    auto * p = new SQLMsg;

    p->m_pkSQL = &m_hDB;
    p->iID = ++m_iMsgCount;
    p->stQuery = c_pszQuery;

    PushQuery(p);
}

void CAsyncSQL::ReturnQuery(const char * c_pszQuery, void * pvUserData)
{
    auto * p = new SQLMsg;

    p->m_pkSQL = &m_hDB;
    p->iID = ++m_iMsgCount;
    p->stQuery = c_pszQuery;
    p->bReturn = true;
    p->pvUserData = pvUserData;

    PushQuery(p);
}

void CAsyncSQL::PushQuery(SQLMsg * p)
{
    MUTEX_LOCK(m_mtxQuery.get());

    m_queue_query.push(p);
    //m_map_kSQLMsgUnfinished.insert(std::make_pair(p->iID, p));

    m_sem.Release();

    MUTEX_UNLOCK(m_mtxQuery.get());
}

std::queue<SQLMsg *> m_queue_query;
 
böyle kullanabilirsin

Kod:
Genişlet Daralt Kopyala
void CAsyncSQL::AsyncQuery(const char * c_pszQuery)
{
    auto * p = new SQLMsg;
    p->m_pkSQL = &m_hDB;
    p->iID = ++m_iMsgCount;
    p->stQuery = c_pszQuery;
    PushQuery(p);
    delete p;  // AsyncQuery fonksiyonu tamamlandığında bellek serbest bırakılır
}

void CAsyncSQL::ReturnQuery(const char * c_pszQuery, void * pvUserData)
{
    auto * p = new SQLMsg;

    p->m_pkSQL = &m_hDB;
    p->iID = ++m_iMsgCount;
    p->stQuery = c_pszQuery;
    p->bReturn = true;
    p->pvUserData = pvUserData;
    PushQuery(p);
    delete p;  // ReturnQuery fonksiyon serbset kalınca sil bro
}

void CAsyncSQL::PushQuery(SQLMsg * p)
{
    MUTEX_LOCK(m_mtxQuery.get());

    m_queue_query.push(p);

    m_sem.Release();

    MUTEX_UNLOCK(m_mtxQuery.get());
}
 
Bu tarz kullanım örnekleri çok var Metin2'de. Mesela EffectLib içinde de benzer pek çok sayıda kullanım örneği var.
Böyle durumlarda mevcut noktaya müdahele etmek çoğu zaman farklı hatalara sebep oluyor, @Denizeri24 dediği gibi kullanım senaryosunda silinmesi daha önemli.
 
böyle kullanabilirsin

Kod:
Genişlet Daralt Kopyala
void CAsyncSQL::AsyncQuery(const char * c_pszQuery)
{
    auto * p = new SQLMsg;
    p->m_pkSQL = &m_hDB;
    p->iID = ++m_iMsgCount;
    p->stQuery = c_pszQuery;
    PushQuery(p);
    delete p;  // AsyncQuery fonksiyonu tamamlandığında bellek serbest bırakılır
}

void CAsyncSQL::ReturnQuery(const char * c_pszQuery, void * pvUserData)
{
    auto * p = new SQLMsg;

    p->m_pkSQL = &m_hDB;
    p->iID = ++m_iMsgCount;
    p->stQuery = c_pszQuery;
    p->bReturn = true;
    p->pvUserData = pvUserData;
    PushQuery(p);
    delete p;  // ReturnQuery fonksiyon serbset kalınca sil bro
}

void CAsyncSQL::PushQuery(SQLMsg * p)
{
    MUTEX_LOCK(m_mtxQuery.get());

    m_queue_query.push(p);

    m_sem.Release();

    MUTEX_UNLOCK(m_mtxQuery.get());
}
O şekilde kullanmak daha tehlikeli çünkü m_queue_query kuyruğuna push ediliyor ve o oradan daha silinmemiş oluyor bu seferde kuyrukta saklanan bellek adresleri geçersiz olduğu için hata olacaktır ve ya çökme olacaktır ya kuyruk için unique_ptr kullanmayı düşündüm ya da new SQLMsg yerine std::make_unique<SQLMsg>() kullanmayı düşündüm. eğer böyle yaparsam PushQuery(p); yerine ise PushQuery(std::move(p)); ile taşıma işlemi yapıp SQLMsg boşa düşecek ve otomatikmen delete olacak en iyi çözüm bu görünüyor ama başka yerde silme işlemi varsa bu yapılan düzenlemeler patlama riski olabilir diye araştırıyorum
 
Bu tarz kullanım örnekleri çok var Metin2'de. Mesela EffectLib içinde de benzer pek çok sayıda kullanım örneği var.
Böyle durumlarda mevcut noktaya müdahele etmek çoğu zaman farklı hatalara sebep oluyor, @Denizeri24 dediği gibi kullanım senaryosunda silinmesi daha önemli.
evet çok haklısın @Denizeri24 nin söylediğini baz alarak hiç dokunmamak çünkü söylediği fonksiyonda silme işlemi gerçekleşiyor
 
Geri
Üst