使用动态内存从转发列表中泄漏内存

时间:2017-12-28 17:07:55

标签: c++ vector memory-leaks forward-list

我为我的班级编写了一个作业,无法完成最后一个要求,即它不会泄漏内存。 Animation.cpp,Frame.cpp和Display.cpp共有3个主要类。动画包含Frame对象的forward_list,Frame包含显示对象的向量。我无法根据分配要求编辑.h文件,这意味着无法更改析构函数。

我认为问题源于在转发列表中为每个帧使用动态内存分配,称为" frames"。因为"帧"和" fileName"是私有类成员我以后使用迭代器来调用delete时无法访问它们。

我尝试在将每个帧对象添加到转发列表之前删除每个帧对象的动态内存分配,但之后帧不会打印出来。这令我感到困惑,因为我之前认为前向列表模板管理了自己的内存。

简短的版本是我必须构建一个名为deleteFrames()的方法在Animation.cpp类中它仍然会泄漏内存

Animation.cpp

#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;

#include "Display.h"
#include "Frame.h"
#include "Animation.h"
#include "GPUMemoryDisplay.h"
#include "SystemMemoryDisplay.h"

void Animation::InsertFrame() {

    int numDisplays;        //for user input of display number
    vector <Display*>v;     //vector for containing display objects
    int p_x;                //will contain user input for pixel_x
    int p_y;                //will contain user input for pixel_y
    int p_duration;         //will contain user input for duration
    int p_type ;            //will contain display type as int value
    char * p_name;          //temp string to contain user input for name
    string d_name;          //will contain p_name to be passed to display constructor
    string frameName;       //contains user input for the frame name
    string gpu_shader;      //contains gpu name if gpu type is selected
    int q = 0;              //used to count the diplay #

    //begin reading user input
    cout << "Insert a Frame in the Animation\nPlease enter the Frame filename: ";
    cin >> frameName;
    cout << "Entering the Frame Displays (the sets of dimensions and durations) " << endl;
    cout << "Please enter the number of Displays: ";
    cin >> numDisplays;

    //display creation loop for # of displays entered
    while (numDisplays > 0) {
        cout << "Please enter pixel x-width for Display #" << q << " pixel_x:";
        cin >> p_x;
        cout << "Please enter pixel y-width for Display #" << q << " pixel_y:";
        cin >> p_y;
        cout << "Please enter the duration for this Display: ";
        cin >> p_duration;
        cout << "Please enter the name for this Display: ";
        cin >> d_name;
        cout << "Please enter the type for this display (1 = SystemMemoryDisplay, 2 = GPUMemoryDisplay): ";
        cin >> p_type;
        p_name = new char[d_name.length() + 1]; //allocate for the size of the name entered
        strcpy(p_name, d_name.c_str()); //copy string to char []

        if (p_type == 2) {
            //input for GPU shader
            cout << "Please enter the file name of the associated GPU Shader: ";
            cin >> gpu_shader;
            Display *gpu_p = new GPUMemoryDisplay(p_x, p_y, p_duration, p_name, gpu_shader);
            v.push_back(dynamic_cast <Display*>(gpu_p)); //casting to a display* and pushing onto the vector
            numDisplays--;
            q++;
        }
        else {
            Display *sm_p = new SystemMemoryDisplay(p_x, p_y, p_duration, p_name);
            v.push_back(dynamic_cast <Display*>(sm_p));//casting to a display* and pushing onto the vector
            numDisplays--;
            q++;
        }
        cout << "\n";
    }


    Frame *t_frame = new Frame(frameName, v); //new frame holds vector which contains displays


    //check if forward list is empty
    if (frames.empty()) {
        cout << "\nThis is the first Frame in the list \n\n";
        frames.push_front(*t_frame);
    }
    else {
        forward_list <Frame>::iterator it;
        int x = 0; // used for size of current forward_list
        //iterate forward list to obtain the size
        for (it = frames.begin(); it != frames.end(); ++it) {
            x++;
        }
        if (x == 1) {
            it = frames.begin();
            frames.insert_after(it, *t_frame);
        }
        else {

            cout << "There are " << x << " Frame(s) in the list\n" << "Please specify the position, between 0 and " << x << " to insert after : ";
            cin >> x; //read in where user wants to put the frame

            //iterate to desired position and insert
            forward_list <Frame>::iterator it;
            it = frames.begin();
            while (x != 0 && it != frames.end()) {
                it++;
                x--;
            }
            frames.insert_after(it, *t_frame);
        }
    }
}

void Animation::DeleteFrames() {

    /*MUST DELETE FRAMES HERE*/
    forward_list <Frame>::iterator it; //used to iterate over forward_list

    for (it = frames.begin(); it != frames.end(); it++) {
        Frame tmpF = *it;
        it = frames.erase_after(it);
        it.

    }
    frames.clear();

}

Frame.cpp

#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;

#include "Display.h"
#include "Frame.h"
#include "Animation.h"


Frame::Frame(const Frame & q)
{
    fileName = q.fileName;
    displays = q.displays;
}

Display.cpp

#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;
#include "Display.h"
#include "GPUMemoryDisplay.h"


Display::Display(int x, int y, int d, char* n) :pixel_x(x), pixel_y(y), duration(d), name(n) {
}

Display::Display(const Display& p) {
    //copy values from p
    pixel_x = p.pixel_x;
    pixel_y = p.pixel_y;
    duration = p.duration;
    size_t len = strlen(p.name);
    name = new char[len + 1];
    strcpy(name, p.name);
    //cout << pixel_x << pixel_y << duration << name;

}

Frame.h

#pragma once

class Frame
{
    string fileName;
    vector<Display*> displays; 
public:
    Frame(string s, vector<Display*> d) :fileName(s), displays(d) {}
    Frame(const Frame&);
    ~Frame()
    {
        vector<Display*>::iterator it;
        for (it = displays.begin(); it != displays.end(); it++)
            delete *it;
    }
    friend ostream& operator<<(ostream&, Frame&);
};


//Animation.h
#pragma once

class Animation
{
    string name;
    forward_list<Frame> frames;
public:
    Animation(string s) : name(s) {}
    void InsertFrame();
    void DeleteFrames();
    friend ostream& operator<<(ostream&, Animation&);
};

#pragma once

Display.h

class Display
{
protected:  // accessible to derived classes
    int pixel_x;
    int pixel_y;
    int duration;
    char* name;
public:
    Display(int x, int y, int duration, char* name);
    Display(const Display&);
    virtual ~Display() //makes class abstract, cannot be instantiated, most general class
    {
        if (name)
            delete[]name;
    }
    virtual int BufferSize() = 0; // overridden function Polymorphic function
    friend ostream& operator<<(ostream&, Display&);
};

我使用ostream /重载运算符打印出来但是我没有包含它来尝试保持简单。

内存泄漏输出

The thread 0x193c has exited with code 0 (0x0).
The thread 0x2530 has exited with code 0 (0x0).
The thread 0xce8 has exited with code 0 (0x0).
Detected memory leaks!
Dumping objects ->
{236} normal block at 0x010E7650, 4 bytes long.
 Data: < w  > D0 77 0E 01 
{235} normal block at 0x010ED928, 8 bytes long.
 Data: < ;      > 8C 3B 0E 01 00 00 00 00 
{234} normal block at 0x010ED9D0, 8 bytes long.
 Data: <p;      > 70 3B 0E 01 00 00 00 00 
{230} normal block at 0x010E3B70, 44 bytes long.
 Data: <    Frame1      > D0 D9 0E 01 46 72 61 6D 65 31 00 CD CD CD CD CD 
Object dump complete.
The program '[4292] Assignment3.exe' has exited with code 0 (0x0).

1 个答案:

答案 0 :(得分:0)

section

短版工作正常