简体   繁体   中英

memory leaks in c++

#pragma once


#ifndef SDDS_GIFT_H
#define SDDS_GIFT_H


#include <iostream>

namespace sdds
{
    const int MAX_DESC = 15;
    const double MAX_PRICE = 999.999;
    const int MAX_WRAP = 20;

    struct Gift
    {
        char m_description[MAX_DESC];
        double m_price;
        int m_units;
        int m_wrapLayers;
        struct Wrapping* m_wrap;
    };

    struct Wrapping 
    {
        char* m_pattern;
    };

    void gifting(char*);
    void gifting(double&);
    void gifting(int&);
    bool wrap(Gift& theGift);
    bool unwrap(Gift& theGift);
    void gifting(Gift& theGift);
    void display(const Gift& theGift);
}

#endif








<pre><code>
    #include <iostream>
    #include "Gift.h"

    using namespace std;
    namespace sdds
    {
        void gifting(char* m_description) // sending info
        {
            cout << "Enter gift description: ";
            cin.width(MAX_DESC + 1);
            cin >> m_description;
        }
        void gifting(double& m_price)
        {
            cout << "Enter gift price: ";
            cin >> m_price;
            while (m_price > MAX_PRICE || m_price < 0)
            {
                cout << "Gift price must be between 0 and " << MAX_PRICE << std::endl;
                cout << "Enter gift price: ";
                cin >> m_price;
            }
        }
        void gifting(int& m_units)// gifting function
        {
            cout << "Enter gift units: ";
            cin >> m_units;
            while (m_units < 1)
            {
                cout << "Gift units must be at least 1" << std::endl;
                cout << "Enter gift units: ";
                cin >> m_units;
            };
        }


        bool wrap(Gift& m_wrap) {
            if (m_wrap.m_wrapLayers > 0) {
                cout << "Gift is already wrapped!" << endl;
                return false;
            }
            else {
                cout << "Wrapping gifts..." << endl;
                cout << "Enter the number of wrapping layers for the Gift: ";
                cin >> m_wrap.m_wrapLayers;

                while (m_wrap.m_wrapLayers < 1) {
                    cout << "Layers at minimum must be 1, try again." << endl;
                    cout << "Enter the number of wrapping layers for the Gift: ";
                    cin >> m_wrap.m_wrapLayers;
                }
                int i = 0;

                m_wrap.m_wrap = new Wrapping[MAX_WRAP + 1];
                for (i = 0; i < m_wrap.m_wrapLayers; i++) {
                    m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
                    cout << "Enter wrapping pattern #" << i + 1 << ": ";
                    cin >> m_wrap.m_wrap->m_pattern;
                } // I put struct in a structure
                return true;
            }
            delete[]m_wrap.m_wrap;
            m_wrap.m_wrap = nullptr;
        }

        bool unwrap(Gift& g_unwrap) // unwrap function
        {
            if (g_unwrap.m_wrapLayers > 0) {
                cout << "Gift being unwrapped." << endl;
                g_unwrap.m_wrapLayers = 0;
                g_unwrap.m_wrap->m_pattern = nullptr;

                return true;
            }
            else 
            {
                cout << "Gift isn't wrapped! Can't unwrap." << endl;
                return false;
            }
        }

        void display(const Gift& theGift)
        {
            cout << "Gift Details:" << endl;
            cout << " Description: " << theGift.m_description << endl;
            cout << "       Price: " << theGift.m_price << endl;
            cout << "       Units: " << theGift.m_units << endl;

            if (theGift.m_wrap == nullptr) // this part seems like a problem
            {
                cout << "Unwrapped" << endl;
            }
            else 
            {
                int i = 0;
                cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
                for (i = 0; i < theGift.m_wrapLayers; i++) {
                    cout << "Wrap #" << i + 1 << ": " << theGift.m_wrap[i].m_pattern << endl;
                }
            }

        }

        void gifting(Gift& gift) //last function
        {
            cout << "Preparing a gift..." << endl;
            gifting(gift.m_description);
            gifting(gift.m_price);
            gifting(gift.m_units);
            wrap(gift);
        }
    }






 </code></pre>

    /***********************************************************************
// Workshop 2: Dynamic Memory & Function Overloading
// Version 2.0
// Date 2020/05/05
// Author Michael Huang
// Description
// Tests Gift module and provides a set of TODOs to complete
// which the main focuses are dynamic memory allocation
//
/////////////////////////////////////////////////////////////////
***********************************************************************/

#include <iostream>
#include "Gift.h"
#include "Gift.h" // intentional
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);
}
<pre><code>
int main() {

    Gift g1; // Unwrapped Gift

    {
        printHeader("T1: Checking Constants");

        cout << "MAX_DESC: " << sdds::MAX_DESC << endl;
        cout << "MAX_PRICE: " << sdds::MAX_PRICE << endl;
        cout << "MAX_WRAP: " << sdds::MAX_WRAP << endl;
        cout << endl;
    }

    {
        printHeader("T2: Display Wrapped Gift");

        gifting(g1.m_description);
        gifting(g1.m_price);
        gifting(g1.m_units);
        cout << endl;

        g1.m_wrap = nullptr;
        g1.m_wrapLayers = 0;
        display(g1);
        cout << endl;
    }

    {
        printHeader("T3: Wrap a gift");

        if (wrap(g1))
            cout << "Test succeeded!";
        else
            cout << "Test failed: wrapping didn't happen!" << endl;
        cout << endl << endl;
    }

    {
        printHeader("T4: Re-wrap a gift");

        cout << "Attempting to rewrap the previous Gift: "
             << g1.m_description << endl;

        if (wrap(g1) == false)
            cout << "Test succeeded!";
        else
            cout << "Test failed: gift it's already wrapped, cannot wrap again!";
        cout << endl << endl;
    }

    {
        printHeader("T5: Unwrap a gift");

        cout << "Attempting to unwrap the previous gift: "
             << g1.m_description << endl;
        if (unwrap(g1))
            cout << "Test succeeded!";
        else
            cout << "Test failed: you should be able to unwrap!";
        cout << endl << endl;
    }


    {
        printHeader("T6: Unwrap again");

        cout << "Attempting to un-unwrap the previous gift: "
             << g1.m_description << endl;

        if (!unwrap(g1))
            cout << "Test succeeded!";
        else
            cout << "Test failed: you should not be able to unwrap again!";
        cout << endl << endl;
    }

    Gift g2; // Unwrapped Gift
    {
        printHeader("T7: Prepare another gift");
        g2.m_wrap = nullptr;
        g2.m_wrapLayers = 0;
        gifting(g2);

        cout << endl;
        display(g2);
        cout << endl;
    }

    {
        printHeader("T8: Unwrap the second gift");

        unwrap(g2);
    }



    return 0;
}

Output matches perfectly but I don't know why memory leaks.. please help me. I am doubting my wrap part but I think there must be something else since deallocation seems fine.

I tried my best but I still cannot see which part is wrong.

I cannot see why my deallocation does not work I tried changing it so many times but nothing works.

On this line:

m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];

You allocate memory, but later you only:

delete[]m_wrap.m_wrap;

Also in your for loop you allocate memory, then get some input and store that inside the pointer, as a memory address. Should you ever dereference that, you will invoke undefined behavior, in practice that may likely will a segfault. You should consider rewriting at least that part from scratch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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