使用valgrind修复内存泄漏

时间:2012-10-21 10:31:07

标签: c++ memory-leaks valgrind

我正在使用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;
};

1 个答案:

答案 0 :(得分:2)

valgrind所能告诉你的只是泄漏的根源。它无法告诉您delete缺少调用的位置 - 它已丢失。

一种解决方案是在将指针弹出堆栈后删除指针,并让VOMC::~VOMC()删除堆栈中剩余的所有元素。只有当类VOMC“拥有”堆栈中的每个对象时,此方法才有效。如果堆栈还包含指向某些其他对象所拥有的State个对象的指针,则此方法无效。

处理混合所有权对于原始指针的容器来说有点困难。处理混合所有权的原始指针容器的一种方法是向类owned_by添加State指针(或者包含的任何内容)。现在,您的班级VOMC仅删除this所拥有的对象。这里有一个架构问题:它充满了代码味道。 SWIG中存在类似于此方法的模拟,有时您需要将thisown属性设置为false。当我看到类似的东西时,我的代码气味传感器会变得很高。

第三种方法是摆脱那些原始指针。而不是原始指针的集合,使您的vomc数据成员成为对象(而不是指针)的集合,这些对象是某种智能指针的实例。这是处理原始指针的现代方法,不使用原始指针。