Ошибки в обработке умных указателей - PullRequest
0 голосов
/ 15 апреля 2019

Я изо всех сил пытаюсь понять, как работают умные указатели.Мне нужно выполнить практическое упражнение, где я должен написать три класса: базовый класс и два производных класса «Файл» и «Каталог», чтобы имитировать файловую систему.Базовый класс - это абстрактный класс со строкой.

Я написал все методы, которые хочу использовать, ожидаю, что метод ls (), который я только что заполнил простой печатью, и попытался запустить простую программу, но компилятор возвращает ошибки, которые я не могучтобы понять.

Я недавно начал работать со смарт-указателем, поэтому я, вероятно, что-то делаю неправильно, обрабатывая их.

Вот мой UDT.h


#ifndef UDT_H
#define UDT_H

#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <memory>

class Base {
    private:
        std::string name;

    public:
        std::string getName() const;                // --> returns name

        explicit Base(std::string name): name(name){};
        virtual int mType () const = 0;             // returns 1 if Dir and 2 if File
        virtual void ls (int indent) const = 0;
};

class File: public Base{
    private:
        uintmax_t sizeFile;

    public:
        int mType () const override{return 2;};

        File(std::string name, uintmax_t size);     // --> class file constructor

        uintmax_t getSize () const;
        void ls (int indent = 0) const override;    // --> print the name of the file with the correct indentation
};

class Directory: public Base{                       // implemented with private constructor in order to have just one root
    public:
        int mType () const override{return 1;};

        static std::shared_ptr<Directory> getRoot();                // --> returns the shared pointer to the root
        std::shared_ptr<Directory> addDirectory(std::string name);  // --> adds one sub directory
        std::shared_ptr<File> addFile(std::string name, uintmax_t size);    // adds one file to the directory

        std::shared_ptr<Base> get (std::string name);               // --> returns shared pointer to the file/dir with name == name
        std::shared_ptr<Directory> getDir (std::string name);       // --> returns shared pointer to the file/dir with name == name
        std::shared_ptr<File> getFile (std::string name);           // --> returns shared pointer to the file/dir with name == name

        void remove (std::string name);
        void ls (int indent = 0) const override;                    // --> print the content of the dir with the correct indentation

    private:
        std::weak_ptr<Directory> myself;                            // --> weak pointer to itself
        std::weak_ptr<Directory> parent;                            // --> weak pointer to parent
        static std::shared_ptr<Directory> root;                     // --> shared pointer to root
        std::vector<std::shared_ptr<Base>> list;                    // --> list of dir/file(s) in the directory
        explicit Directory(std::string name, std::shared_ptr<Directory> parent);    // --> dir constructor
};



#endif //UDT_H

ВотUDT.cpp


#include "UDT.h"

std::shared_ptr<Directory> Directory::root;

std::string Base::getName() const {
    return this->name;
}

Directory::Directory(std::string name, std::shared_ptr<Directory> parent): Base(name) {
    this->parent = parent;
    this->myself = std::shared_ptr<Directory>(this);
}

File::File(std::string name, uintmax_t size):Base(std::move(name)) {
    sizeFile = size;
}

std::shared_ptr<Directory> Directory::getRoot() {
    if (root == nullptr){ // --> create root directory if not already created
        root = std::shared_ptr<Directory>(new Directory("/", nullptr));
    }
    return root;
}

std::shared_ptr<Directory> Directory::addDirectory(std::string name) {
    if (name == "." || name == "..")
        throw std::exception();

    for(int i = 0 ; i < list.size() ; i++){
        if(list[i]->getName() == name)
            throw std::exception(); // object with the same name --> throw exception
    }

    // if no object with the same name --> add it!

    std::shared_ptr<Directory> newDir = std::shared_ptr<Directory>(new Directory(name, this->myself.lock()));
    return newDir;
}

std::shared_ptr<File> Directory::addFile(std::string name, uintmax_t size) {
    if (name == "." || name == "..")
        throw std::exception();

    for(int i = 0 ; i < list.size() ; i++){
        if(list[i]->getName() == name)
            throw std::exception(); // object with the same name --> throw exception
    }

    // if no object with the same name --> add it!
    std::shared_ptr<File> newFile = std::make_shared<File>(name, size);
    return newFile;
}

std::shared_ptr<Base> Directory::get(std::string name) {
    if (name == "." )
        return std::shared_ptr<Base>(this->myself);

    if (name == ".." )
        return std::shared_ptr<Base>(this->parent);

    for(int i = 0 ; i < list.size() ; i++){
        if(list[i]->getName() == name)
            return list[i];
    }

    return nullptr;
}

std::shared_ptr<Directory> Directory::getDir(std::string name) {
    if (name == "." )
        return this->myself.lock();

    if (name == ".." )
        return this->parent.lock();

    for(int i = 0 ; i < list.size() ; i++){
        if(list[i]->getName() == name)
            return std::dynamic_pointer_cast<Directory>(list[i]);
    }

    return nullptr;
}

std::shared_ptr<File> Directory::getFile(std::string name) {
    if (name == "." || name == ".." )
        return nullptr;

    for(int i = 0 ; i < list.size() ; i++){
        if(list[i]->getName() == name)
            return std::dynamic_pointer_cast<File>(list[i]);
    }

    return nullptr;
}

void Directory::remove(std::string name) {
    if (name == "." || name == "..")
        throw std::exception();

    for(int i = 0; i < list.size() ; i++){
        if (list[i]->getName() == name){
            list.erase(list.begin() + i);
        }
    }
}

uintmax_t File::getSize() const {
    return sizeFile;
}

void Directory::ls(int indent) const {
    std::cout << "ls" << std::endl;
}

void File::ls(int indent) const {
    std::cout << "ls" << std::endl;
}

И main.cpp


#include <iostream>
#include "UDT.h"

int main() {

    std::shared_ptr <Directory> root = Directory::getRoot();
    auto alfa = root -> addDirectory( "alfa");
    alfa -> addDirectory("beta") -> addFile( "beta1", 100);
    alfa -> getDir("beta") -> addFile( "beta2", 200);
    alfa -> getDir("..") -> ls();
    alfa -> remove("beta");
    root -> ls();

    return 0;
}

Я получаю эту ошибку: (5486,0x114c015c0) malloc: *** error for object 0x6000000000000000: pointer being freed was not allocated (5486,0x114c015c0) malloc: *** set a breakpoint in malloc_error_break to debug

Пожалуйста, помогите мне понять, в чем проблема

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...