我正在使用c ++并使用valgrind来修复内存泄漏。 我正在尝试优化valgrind描述为泄漏的以下代码:
void VOMC::sub_train(vector<Letter> tempLettersA, vector<Letter> tempLettersB) {
int stateA_id = state_exists(tempLettersA);
State *tempStateA;
if (stateA_id != -1) {
tempStateA = get_state_by_id(stateA_id);
} else {
tempStateA = new State(tempLettersA);// MEMORY LEAK - 1
vomc.push_back(tempStateA);
}
int stateB_id = state_exists(tempLettersB);
if (stateB_id != -1) {
tempStateA->inc_state(stateB_id);
} else {
State* tempStateB;
tempStateB = new State(tempLettersB);//MEMORY LEAK -2
vomc.push_back(tempStateB);
stateB_id = tempStateB->GetId();
tempStateA->inc_state(stateB_id);
}
}
对于内存泄漏-1,我收到以下消息
==11289== 4,055 (64 direct, 3,991 indirect) bytes in 1 blocks are definitely lost in loss record 228 of 228
==11289== at 0x402B87E: operator new(unsigned int) (vg_replace_malloc.c:292)
==11289== by 0x807FA75: VOMC::sub_train(std::vector<Letter, std::allocator<Letter> >, std::vector<Letter, std::allocator<Letter> >) (VOMC.cpp:952)
内存泄漏-2
==11289== at 0x402B87E: operator new(unsigned int) (vg_replace_malloc.c:292)
==11289== by 0x807FB16: VOMC::sub_train(std::vector<Letter, std::allocator<Letter> >, std::vector<Letter, std::allocator<Letter> >) (VOMC.cpp:968)
我可以删除这些指针吗?这会消除我的泄漏但是你可以看到指针被推入堆栈,目标是将它们保存在堆栈中但是除去泄漏。
编辑-1:添加字母和状态定义:
class Letter {
public:
Letter();
Letter(Helper *helper);
~Letter();
void add_note(RawNote r);
void evaluate_letter(double eigthNoteDuration);
void setNotePositionAccordingToLetter();
void empty_notes();
LetterPattern getPattern() const;
void setPattern(LetterPattern pattern);
bool isEmpty();
vector<RawNote> getRawNotes() const;
void setRawNotes(vector<RawNote> rawNotes);
bool has_note_no_velocity(RawNote* r1);
bool has_note_with_velocity(RawNote* r1);
private:
vector<LetterPattern> *allPossibleNotes;
vector<RawNote> rawNotes;
LetterPattern pattern;
};
class State {
public:
State(); //should not be used, it is only for testing
State(vector<Letter> letters);
virtual ~State();
int GetId() const;
void SetId(int id);
vector<Letter> GetLetters() const;
void SetLetters(vector<Letter> letters);
void AddLetters(vector<Letter> letters);
void inc_state(int state_id);
void print_state_letters();
bool has_state(int state_id);
void print_connected_states();
void print_sorted_states();
vector<string> get_rhythm_as_string();
map<int, double> GetConnected_states() const;
map<int, double> connected_states;
vector< pair <int, double > > vector_sorted_connected_states;
void bubblesort_vector_descending(vector< pair <int, double > > *v_sort);
int get_connected_state_stochastically();
static int id_generator;
CustomNumberDist *normal_dist;
int id_from_file; //only used on load of a file
private:
int id;
vector<Letter> letters;
};
答案 0 :(得分:2)
valgrind所能告诉你的只是泄漏的根源。它无法告诉您delete
缺少调用的位置 - 它已丢失。
一种解决方案是在将指针弹出堆栈后删除指针,并让VOMC::~VOMC()
删除堆栈中剩余的所有元素。只有当类VOMC
“拥有”堆栈中的每个对象时,此方法才有效。如果堆栈还包含指向某些其他对象所拥有的State
个对象的指针,则此方法无效。
处理混合所有权对于原始指针的容器来说有点困难。处理混合所有权的原始指针容器的一种方法是向类owned_by
添加State
指针(或者包含的任何内容)。现在,您的班级VOMC
仅删除this
所拥有的对象。这里有一个架构问题:它充满了代码味道。 SWIG中存在类似于此方法的模拟,有时您需要将thisown
属性设置为false。当我看到类似的东西时,我的代码气味传感器会变得很高。
第三种方法是摆脱那些原始指针。而不是原始指针的集合,使您的vomc
数据成员成为对象(而不是指针)的集合,这些对象是某种智能指针的实例。这是处理原始指针的现代方法,不使用原始指针。