Проблема с функцией cout при использовании Valgrind - PullRequest
0 голосов
/ 12 июля 2020

Я использую valgrind для проверки утечек памяти, и я продолжаю получать эту ошибку, и она продолжает указывать на строку cout, и я не могу понять, почему. Я думаю, что это может быть связано с тем, что я неправильно распределяю массивы char, но я проверял их много раз и также переписывал их. Проблема может быть связана с функцией отображения двух классов.

main

#include <iostream>
#include "Utils.h"
#include "Menu.h"
using namespace std;
using namespace sdds;
int showSelection(int n);
void prompt(const char* message);
void pause();
void testMenus(Menu m, Menu sub1, const Menu& sub2);
void TT(const char* title);
int main() {

TT("M1T1: constructors");
Menu mainMenu("** Main Menu **");
Menu subMenu1("** Sub Menu One **", 1);
Menu subMenu2("** Sub Menu **", 2);
Menu tempMenu("** Temp **");
Menu invMenu("** To test Invalid Menu **");

TT("M1T2: operator<< adding MenuItems");
tempMenu << "One" << "Two" << "three";


TT("M1T3: Menu::run()");
prompt("Do the following: \nabc <ENTER>\n0 <ENTER>\n4 <ENTER>\n3 <ENTER>");
cout << tempMenu.run() << " selected!" << endl;
pause();

TT("M1T4: Menu deep assignment with no items");
tempMenu = subMenu2;

Ошибка: Ошибка

Меню. cpp

#include <iostream>
#include <cstring>
#include "Menu.h"

using namespace std;

namespace sdds {
//MenuItem
MenuItem::MenuItem() {
    m_item = nullptr;
}
MenuItem::MenuItem(const char* item) {
    if (item || strlen(item) > 0) {
        int len = strlen(item);
        m_item = new char[len + 1];
        strcpy(this->m_item, item);
        m_item[len] = '\0';
    }
    else {
        m_item = nullptr;
    }
}
void MenuItem::display() const {
        cout << m_item << endl;
}
MenuItem::~MenuItem() {
    if(m_item != nullptr)
        delete[] m_item;
}

//Menu
Menu::Menu() {
    m_name = nullptr;
    indent = 0;
    arrSize = 0;
}
Menu::Menu(const char* name, int iLevel) {
    if ((!name) || (strlen(name) == 0) || (iLevel == 0)) {
        m_name = nullptr;
        indent = 0;
        arrSize = 0;
    }
    else {
        int len = strlen(name);
        m_name = new char[len+1];
        strcpy(m_name, name);
        m_name[len] = '\0';
        indent = iLevel;
        arrSize = 0;
    }
}

Menu::Menu(const Menu& copy) {
    if (copy.m_name != nullptr && copy.arrSize >= 0) {
        this->m_name = new char[strlen(copy.m_name) + 1];
        strcpy(this->m_name, copy.m_name);
        this->m_name[strlen(copy.m_name)] = '\0';
        for (int i = 0; i < arrSize; i++) {
            this->m_Mitems[i] = copy.m_Mitems[i];
        }
        this->arrSize = copy.arrSize;
        this->indent = copy.indent;
    }
    else {
        this->arrSize = 0;
        this->m_name = nullptr;
        this->indent = 0;
    }
}
Menu& Menu::operator=(const Menu& copy) {
    if (m_name != nullptr)
        delete[] m_name;
    this->m_name = new char[strlen(copy.m_name) + 1];
    strcpy(this->m_name, copy.m_name);
    this->m_name[strlen(copy.m_name)] = '\0';
    for (int i = 0; i < arrSize; i++) {
        this->m_Mitems[i] = copy.m_Mitems[i];
    }
    this->arrSize = copy.arrSize;
    return *this;
}

Menu::operator bool() const {
    return m_name != nullptr;
}

bool Menu::isEmpty() {
    return m_name == nullptr;
}

Menu::~Menu() {
    delete[] m_name;
}

void Menu::display() const{
    if (this) {
        if (arrSize == 0) {
            cout << "No Items to display!" << endl;
        }
        else {
            cout.setf(ios::fixed);
            cout.width(indent);
            cout << "** " << " **" << endl;
            for (int i = 0; i < arrSize; i++) {
                cout << "1- ";
                m_Mitems[i].display();
            }
            cout << "> ";
            cout.unsetf(ios::fixed);
        }
    }
    else {
        cout << "Invalid Menu!" << endl;
    }
}
Menu& Menu::operator=(const char* title) {
    delete[] m_name;
    if ((title) || (strlen(title) >= 0)) {
        this->m_name = new char[strlen(title) + 1];
        strcpy(this->m_name, title);
        this->m_name[strlen(title)] = '\0';
    }
    else {
        this->m_name = nullptr;
    }
    return *this;
}
void Menu::add(const char* menuItem) {
    if (menuItem) {
        if (arrSize < MAX_NO_OF_ITEMS) {
            m_Mitems[arrSize] = MenuItem(menuItem);
            arrSize++;
        }
    }
    else {
        if (m_name != nullptr)
            delete[] m_name;
        this->m_name = nullptr;
    }
}
Menu& Menu::operator<<(const char* menuItem) {
    if (menuItem) {
        if (arrSize < MAX_NO_OF_ITEMS) {
            m_Mitems[arrSize] = MenuItem(menuItem);
            arrSize++;
        }
    }
    else {
        if (m_name != nullptr)
            delete[] m_name;
        this->m_name = nullptr;
    }
    return *this;
}
    

int Menu::run(){
    display();
    int ans;
    cin >> ans;
    bool in = false, sel = false;
    while (in && sel) {
        if (isdigit(ans)) {
            in = true;
        }
        if (ans > 0 && ans < arrSize) {
            sel = true;
        }
    }
    return ans;
}
int Menu::operator==(int number) {
    int ans = run();
    return ans;
}

}

Menu.h

#ifndef SDDS_MENU_H
#define SDDS_MENU_H
namespace sdds {
const int MAX_NO_OF_ITEMS = 10;
class MenuItem  {
public:
    char* m_item;
    MenuItem();
    MenuItem(const char* item);
    ~MenuItem();
    void display() const;
};

class Menu : public MenuItem {
    char* m_name;
    MenuItem m_Mitems[MAX_NO_OF_ITEMS];
    int indent;
    int arrSize;
public:
    Menu();
    Menu(const char* name, int iLevel = 0);
    Menu(const Menu& copy);
    ~Menu();
    Menu& operator=(const Menu& copy);
    operator bool() const;
    bool isEmpty();
    void display() const;
    Menu & operator=(const char* title);
    void add(const char* menuItem);
    Menu& operator<<(const char* menuItem);
    int run();
    int operator==(int number);
};
}
#endif // !SDDS_MENU_H
...