我的第一個問題是添加地圖的物件A(v),應該在退出范圍時自動洗掉嗎?
我的第二個問題是,當程式退出時,添加到地圖中的物件會發生什么?我相信當我執行 a_[name] = A(v); 時,會將副本存盤到地圖中。另外,我需要提供一個復制建構式嗎?
void B::AddA(std::string name, int v) {
a_[name] = A(v);
}
我的最后一個問題是我沒有用“new”創建任何物件,我不需要洗掉任何物件。
我不明白泄漏是從哪里來的。
我很感激任何幫助。謝謝你。
完整代碼
#include <map>
#include <string>
#include <iostream>
class A {
public:
int vala_;
A();
~A();
A(int v);
};
A::A() {
vala_ = 0;
}
A::~A() {}
A::A(int v) {
vala_ = v;
}
class B {
public:
int valb_;
std::map<std::string, A> a_;
B();
~B();
void AddA(std::string name, int v);
};
B::B() {
valb_ = 0;
}
B::~B() {
}
void B::AddA(std::string name, int v) {
a_[name] = A(v);
}
int main() {
B b;
b.AddA("wewe", 5);
std::cout << b.a_["wewe"].vala_ << std::endl;
exit(0);
}
瓦爾格林
I replaced the number ==????==, to ==xxxx==. I guess it was the process id.
==xxxx== Memcheck, a memory error detector
==xxxx== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==xxxx== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==xxxx== Command: ./a.out --leak-check=full -s
==xxxx==
5
==xxxx==
==xxxx== HEAP SUMMARY:
==xxxx== in use at exit: 72 bytes in 1 blocks
==xxxx== total heap usage: 3 allocs, 2 frees, 73,800 bytes allocated
==xxxx==
==xxxx== LEAK SUMMARY:
==xxxx== definitely lost: 0 bytes in 0 blocks
==xxxx== indirectly lost: 0 bytes in 0 blocks
==xxxx== possibly lost: 0 bytes in 0 blocks
==xxxx== still reachable: 72 bytes in 1 blocks
==xxxx== suppressed: 0 bytes in 0 blocks
==xxxx== Rerun with --leak-check=full to see details of leaked memory
==xxxx==
==xxxx== For lists of detected and suppressed errors, rerun with: -s
==xxxx== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
uj5u.com熱心網友回復:
==xxxx== in use at exit: 72 bytes in 1 blocks
==xxxx== still reachable: 72 bytes in 1 blocks
這些僅意味著當程式退出時,您仍然有參考的活動記憶體。記憶體并沒有完全丟失,這通常被稱為嚴格意義上的記憶體泄漏,并將在definitely lostorindirectly lost和下列出possibly lost。當程式結束時,是否還有未釋放的記憶體并不重要。
但是,這仍然可能是問題的征兆,例如,如果應該銷毀且具有帶副作用的解構式的物件未運行。
在您的情況下,問題出在exit(0)電話上。呼叫std::exit會在此處結束程式并進行一些清理。清理包括銷毀具有靜態存盤持續時間的物件,但不包括具有自動存盤持續時間的物件,這些物件通常會在離開其范圍時被銷毀。
在您的情況下B b;,包括它存盤的所有元素,通常會在}orreturn陳述句中被銷毀main,但是因為您exit事先呼叫,所以它永遠不會被銷毀。在這種特殊情況下,這不是問題,但如果例如b是一個帶有解構式的物件,它應該執行一些在程式外部可見副作用的操作,那么它可能是。
您不應該呼叫exit(0)從main. 只需使用return 0;或完全省略它,因為main具體而言,沒有 return 陳述句等同于return 0;.
旁注:您不應顯式宣告/定義不做任何事情且不做任何事情的解構式virtual,例如A::~A() {}. 如果您根本沒有在類中宣告解構式,編譯器將自動為您生成它,并且行為完全相同。
無論如何手動宣告解構式會對特殊成員函式的其他隱式生成產生影響,這可能會影響程式的性能,并且也使得始終遵循0/3/5 規則變得更加困難。
我的第一個問題是添加地圖的物件A(v),應該在退出范圍時自動洗掉嗎?
A(v)是一個臨時物件,將在完整運算式結束時銷毀a_[name] = A(v)。
另外,我需要提供一個復制建構式嗎?
不,如果您不手動宣告一個(與解構式相同),編譯器會隱式宣告一個,并且假設這是可能的,它將被定義為簡單地復制每個成員。無論如何,這通常是您想要的。
我的最后一個問題是我沒有用“new”創建任何物件,我不需要洗掉任何物件。
是的,這完全正確。
uj5u.com熱心網友回復:
“仍然可達”并不嚴格意味著它是記憶體泄漏。我相信這是因為你呼叫exit(0)了而不是僅僅回傳 0。堆疊沒有被清理,因為程式被信號終止了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411944.html
標籤:
