因此,我一直致力於內存管理,並且在移動包含捕獲數據的lambda函數對象的對象時遇到特殊問題。假設下面的例子:更新Lambda的參考數據
typedef std::function < void(int) > funcType;
class Something
{
private:
int _myNum = 0;
public:
funcType GetSetIt()
{
return [&] (int a)
{
_myNum = a;
};
}
void SeeIt()
{
std::cout << _myNum << std::endl;
}
int GetIt()
{
return _myNum;
}
};
而下面的操作:
auto destination = (Something*) malloc(sizeof(Something));
auto alt = (funcType*) malloc(sizeof(funcType));
auto size = sizeof(funcType);
auto s = new Something();
auto setIt = s->GetSetIt();
setIt(10);
s->SeeIt();
auto a = s->GetIt();
memcpy(destination, s, sizeof(Something));
memset(s, 0, sizeof(Something));
memcpy(alt, &setIt, sizeof(funcType));
memset(&setIt, 0, sizeof(funcType)); // point 1
(*alt)(15);
destination->SeeIt();
auto b = destination->GetIt();
一個快速的解釋:
創建一個新的Something
並調用它的所有成員,以確保它的正常工作。然後將其移到新位置並刪除/清除它以前存在的位置。同時將函數對象移到新的位置並在之後清理。然後,使用指針到新的位置,調用函數對象和對象上的方法。
第一個問題是,一切正在順利進行,直到我memset
函數對象的原始位置。如果你註釋掉該行(用// point 1
註明),你會注意到它不會崩潰。
這對我來說有點奇怪,但我並不完全理解函數對象是如何在內存中佈局的,並且希望在該區域釋放一點光線。我假設,如果我將整個對象塊複製到另一個區域並清除舊空間(不刪除它,因爲它在堆棧中),它和它的所有引用都將被保留。
第二個問題,假設您已將memset
行註釋掉,則「預期結果」與「預期結果」不同。我預計撥打alt
將s
上的_myNum
設置爲15,就可以了。但我想更新alt
的指針Something
(我通常把它稱爲this
指針)指向destination
。我怎樣才能做到這一點?它可以在編譯器中可靠地完成嗎?我一直擔心,儘管我可以想象找到它的存儲位置並更新了值,但解決方案並不穩固,因爲lambda可以跨編譯器以各種方式實現,並且手頭可能有一些「魔術」。
對這些問題的任何幫助或洞察力都非常感謝。如果我不清楚發生了什麼,評論和我會在需要的地方提供更多細節。提前致謝!
是否有一個原因,你沒有使用'new'和'delete'運算符與'operator ='一起使用?你在做什麼不是慣用的C++。 – thirtythreeforty
這是在我一直在研究的內存管理器中工作情況的基本示例。我不使用'new'和'delete'有幾個原因,所以這主要是爲了說明這個概念。 –
是什麼讓你認爲'將lambda寫入'std :: function'會工作?lambda可以存儲在'std :: function'中,這並不意味着它們是相同的東西,或者佈局兼容。一般來說,從'std :: function'往/從'memcpy'''發送任何東西的機會幾乎不會產生所需的行爲。 – Praetorian