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