简体   繁体   English

需要帮助查找 memory 泄漏

[英]Need help finding a memory leak

I am doing an assignment for school and I have provided the code below and I keep getting a memory leak but I don't understand why its happening.我正在为学校做作业,我提供了下面的代码,我不断收到 memory 泄漏,但我不明白它为什么会发生。 The program used to find the memory leak is valgrind.用于查找 memory 泄漏的程序是 valgrind。 Note: I cant change the main file it was provided by the school and used to mark us.注意:我无法更改学校提供的用于标记我们的主文件。

Saiyan.cpp赛亚人.cpp

#include <iomanip>
#include <cstring>
#include "Saiyan.h"

using namespace std;

namespace sdds
{
    Saiyan::Saiyan()
    {
        m_name = nullptr;
        m_dob = 0;
        m_power = -1;
        m_level = -1;
        m_super = false;
    }
    Saiyan::Saiyan(const char* name, int dob, int power)
    {       
        set(name, dob, power);
    }
    
    void Saiyan::set(const char* name, int dob, int power,int level, bool super)
    {
        
        if (!name || strlen(name) == 0 || dob > 2020 || power <= 0 || level < 0)
        {
            
            this->m_name = nullptr;
            this->m_dob = 0;
            this->m_power = -1;
            this->m_level = -1;
            this->m_super = false;
        }
        else
        {
            int len = strlen(name);
            m_name = new char[len + 1];
            strcpy(this->m_name, name);
            this->m_name[len] = '\0';
            this->m_dob = dob;
            this->m_power = power;
            this->m_super = super;
            this->m_level = level;
        }
    }
    bool Saiyan::isValid() const
    {
        return this->m_name != nullptr;
    }
    void Saiyan::display() const
    {
        
        if (isValid())
        {
            cout << this->m_name << endl;
            cout.width(10);
            cout << "DOB: " << m_dob << endl;
            cout.width(10);
            cout << "Power: " << m_power << endl;
            cout.width(10);
            cout << "Super: ";
            if (m_super)
            {
                cout << "yes" << endl;
                cout.width(10);
                cout << "Level: " << m_level << endl;
            }
            else
            {
                cout << "no" << endl;
            }
        }
        else
        {
            cout << "Invalid Saiyan!" << endl;
        }
    }
    bool Saiyan::fight(Saiyan& other)
    {
        bool cond = false;
        if (isValid() && other.isValid())
        {
            if (this->m_super)
            {
                this->m_power += (int)((10/100) *this->m_level* this->m_power);
            }
            if (other.m_super)
            {
                other.m_power += (int)((10/100) * other.m_level * other.m_power);
            }

            if (m_power > other.m_power)
            {
                cond = true;
            }
        }
        return cond;
    }
    Saiyan::~Saiyan()
    {
        delete [] this->m_name;
    }
}

Saiyan.h赛亚人.h

#ifndef SDDS_SAIYAN_H
#define SDDS_SAIYAN_H


namespace sdds
{
    class Saiyan
    {
        char* m_name;
        int m_dob;
        int m_power;
        int m_level;
        bool m_super;
    public:
        Saiyan();
        ~Saiyan();
        Saiyan(const char* name, int dob, int power);
        void set(const char* name, int dob, int power,int level = 0, bool super = false);
        bool isValid() const;
        void display() const;
        bool fight(Saiyan& other);

    };
}

#endif // !SDDS_SAIYAN_H

main.cpp主文件

#include <iostream>
#include "Saiyan.h"
#include "Saiyan.h"  // this is on purpose

using namespace std;
using namespace sdds;

void printHeader(const char* title)
{
    char oldFill = cout.fill('-');
    cout.width(40);
    cout << "" << endl;

    cout << "|> " << title << endl;

    cout.fill('-');
    cout.width(40);
    cout << "" << endl;
    cout.fill(oldFill);
}


int main()
{
    {
        printHeader("T1: Checking default constructor");

        Saiyan theSayan;
        theSayan.display();
        cout << endl;
    }

    {
        printHeader("T2: Checking custom constructor");

        Saiyan army[] = {
          Saiyan("Nappa", 2025, 1),
          Saiyan("Vegeta", 2018, -1),
          Saiyan("Goku", 1990, 200),
          Saiyan(nullptr, 2015, 1),
          Saiyan("", 2018, 5)
        };

        cout << "Only #2 should be valid:" << endl;
        for (int i = 0; i < 5; i++)
        {
            cout << "  Sayan #" << i << ": " << (army[i].isValid() ? "valid" : "invalid") << endl;
        }
        for (int i = 0; i < 5; i++)
        {
            army[i].display();
        }
        cout << endl;
    }

    // valid saiyans
    Saiyan s1("Goku", 1990, 2000);
    Saiyan s2;
    s2.set("Vegeta", 1989, 2200);

    {
        printHeader("T3: Checking the fight");
        s1.display();
        s2.display();

        cout << "S1 attacking S2, Battle " << (s1.fight(s2) ? "Won" : "Lost") << endl;
        cout << "S2 attacking S1, Battle " << (s2.fight(s1) ? "Won" : "Lost") << endl;
        cout << endl;
    }

    {
        printHeader("T4: Checking powerup");
        s1.set("Goku", 1990, 1900, 1, true);
        int round = 0;
        bool gokuWins = false;
        while (!gokuWins) // with every fight, the super saiyan should power up
        {
            cout << "Round #" << ++round << endl;
            gokuWins = s1.fight(s2);
            s1.display();
            s2.display();
        }

        cout << "Bonus round. Is s2 winning? " << (s2.fight(s1) ? "yes" : "no") << endl;
        s1.display();
        s2.display();
        cout << endl;
    }

    {
        printHeader("T5: Upgrading s2");
        s2.set("Vegeta", 1990, 2200, 3, true);

        cout << "Super Battle. Is s2 winning? " << (s2.fight(s1) ? "yes" : "no") << endl;
        s1.display();
        s2.display();
        cout << endl;
    }

    return 0;
}

The memory leak memory 泄漏

==211503==
==211503== HEAP SUMMARY:
==211503==     in use at exit: 12 bytes in 2 blocks
==211503==   total heap usage: 5 allocs, 3 frees, 29 bytes allocated
==211503==
==211503== 5 bytes in 1 blocks are definitely lost in loss record 1 of 2
==211503==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==211503==    by 0x400BC1: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:38)
==211503==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==211503==    by 0x401241: main (main_prof.cpp:66)
==211503==
==211503== 7 bytes in 1 blocks are definitely lost in loss record 2 of 2
==211503==    at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==211503==    by 0x400BC1: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:38)
==211503==    by 0x401274: main (main_prof.cpp:68)
==211503==
==211503== LEAK SUMMARY:
==211503==    definitely lost: 12 bytes in 2 blocks
==211503==    indirectly lost: 0 bytes in 0 blocks
==211503==      possibly lost: 0 bytes in 0 blocks
==211503==    still reachable: 0 bytes in 0 blocks
==211503==         suppressed: 0 bytes in 0 blocks

Edit: After doing what was suggested I add deallocated the memory but these errors came up.编辑:按照建议我添加释放 memory 但这些错误出现了。

New Errors:新错误:

==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x400B77: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:29)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x4010DC: main (main_prof.cpp:51)
==218753==
==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x400B77: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:29)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x4010FC: main (main_prof.cpp:51)
==218753==
==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x400BDA: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:41)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x40111B: main (main_prof.cpp:51)
==218753==
==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x400B77: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:29)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x40113A: main (main_prof.cpp:51)
==218753==
==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x400B77: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:29)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x401159: main (main_prof.cpp:51)

==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x400BDA: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:41)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x401285: main (main_prof.cpp:66)
==218753==
==218753== Conditional jump or move depends on uninitialised value(s)
==218753==    at 0x4C2BB42: operator delete[](void*) (vg_replace_malloc.c:651)
==218753==    by 0x400BEA: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:41)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x401285: main (main_prof.cpp:66)
==218753==
==218753== Invalid free() / delete / delete[] / realloc()
==218753==    at 0x4C2BB8F: operator delete[](void*) (vg_replace_malloc.c:651)
==218753==    by 0x400BEA: sdds::Saiyan::set(char const*, int, int, int, bool) (Saiyan.cpp:41)
==218753==    by 0x400B23: sdds::Saiyan::Saiyan(char const*, int, int) (Saiyan.cpp:20)
==218753==    by 0x401285: main (main_prof.cpp:66)
==218753==  Address 0x1ffefffec0 is on thread 1's stack
==218753==  in frame #3, created by main (main_prof.cpp:33)

program edit:节目编辑:

 void Saiyan::set(const char* name, int dob, int power,int level, bool super)
        {

                if (!name || strlen(name) == 0 || dob > 2020 || power <= 0 || level < 0)
                {
                        delete [] this->m_name;
                        this->m_name = nullptr;
                        this->m_dob = 0;
                        this->m_power = -1;
                        this->m_level = -1;
                        this->m_super = false;
                }
                else
                {


                        int len = strlen(name);
                        delete [] this->m_name;
                        m_name = new char[len + 1];
                        strcpy(this->m_name, name);
                        this->m_name[len] = '\0';
                        this->m_dob = dob;
                        this->m_power = power;
                        this->m_super = super;
                        this->m_level = level;
                }
        }

you need to delete the m_name in set function before reusing it:您需要在重用之前删除集合 function 中的 m_name:

void Saiyan::set(const char* name, int dob, int power, int level, bool super)
    {
        
        if (!name || strlen(name) == 0 || dob > 2020 || power <= 0 || level < 0)
        {
            
            delete [] this->m_name; \\<-- delete
            this->m_name = nullptr;
            this->m_dob = 0;
            this->m_power = -1;
            this->m_level = -1;
            this->m_super = false;
        }
        else
        {
            int len = strlen(name);
            delete [] this->m_name; \\<-- delete
            m_name = new char[len + 1];
            strcpy(this->m_name, name);
            this->m_name[len] = '\0';
            this->m_dob = dob;
            this->m_power = power;
            this->m_super = super;
            this->m_level = level;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM