0

I am trying to create a program that simulates folder and file creation. I have created a class Folder that has an attribute Folder *prev which should point to the parent Folder.

The problem is that every folder I am creating always points to the current folder. Please check cd() and mkdir() functions.


#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <String>
#include <stdio.h>
using namespace std;

int MAX_PER_FOLDER = 100;
int MAX_FILES_PER_FOLDER = 100;

struct File;

class Folder {
    public:
        Folder() {}
    string name;
    int nFolders;
    int nFiles;
    File *files;
    Folder *folders;
    Folder * prev;
};

struct File {
    string name;
    int size;
    Folder *folder;
    string data;
};

void ls(Folder root) {
    for (int i = 0; i < root.nFolders; i++) {
        Folder temp = root.folders[i];
        std::cout << " - " << temp.name << endl;
    }
}


void mkdir(string name, Folder &current) {
    Folder *temp = new Folder();
    temp->name = name;
    temp->prev = &current;
    temp->nFolders = 0;
    temp->nFiles = 0;
    temp->folders = new Folder[MAX_PER_FOLDER];
    temp->files = new File[MAX_FILES_PER_FOLDER];
    current.folders[current.nFolders] = *temp;
    current.nFolders++;
}

void cfile(string name, Folder &current, string data) {
    File temp;
    temp.name = name;
    temp.folder = &current;
    temp.data = data;
    current.files[current.nFiles] = temp;
    current.nFiles++;
}

void cd(string name, Folder &current) {
    bool found = false;
    if (name == ".." && current.prev != NULL) {
        cout << "====";
        current = *current.prev;
        cout << "---";
        found = true;
    }
    else {
        for (int i = 0; i < current.nFolders; i++) {
            Folder f = current.folders[i];
            if (f.name == name) {
                current = f;
                found = true;
                break;
            }
        }
    }
    if (found) {
        cout << "Current dir: " << current.name << endl;
    }
    else
        cout << "Directory does not exist" << endl;

}

int main()
{
    Folder root = Folder();
    root.folders = new Folder[MAX_PER_FOLDER];
    root.nFiles = 0;
    root.nFolders = 0;
    root.prev = NULL;
    root.name = "root";

    mkdir("Test1", root);
    mkdir("Test2", root);
    mkdir("Test3", root);

    ls(root);

    cd("Test3", root);
    mkdir("Test3.1", root);
    mkdir("Test3.2", root);
    mkdir("Test3.3", root);

    ls(root);

    cd("Test3.1", root);
    mkdir("Test3.1.2", root);
    mkdir("Test3.1.3", root);
    mkdir("Test3.1.4", root);

    cd("Test3.1.2", root);

    cd("..", root);
    ls(root);

    system("PAUSE");

    return 0;
}

The problem is that all folders created always point to the current folder that is set by cd(), I believe it exists within the following line: temp->prev = &current; when creating the folder, because maybe it points to only one address which is the address of the current folder.

Thanks!

user7864052
  • 91
  • 1
  • 1
  • 7
  • Sorry about that. – Max Langhof Jun 07 '19 at 14:49
  • Your program leaks memory. Every last bit of it. You must `delete` what you `new`! – Max Langhof Jun 07 '19 at 14:50
  • (Also, you technically have a tree here, not a linked list). – Max Langhof Jun 07 '19 at 15:00
  • 1
    Sidenote: `void ls(Folder root)` passes `root` by value . Once you fix up the memory leak @MaxLanghof wrote of you're going to get a first-hand experience with [The Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Trust me you want to read the link. It's a lot more fun if you know what's going on before you try to debug what's coming. – user4581301 Jun 07 '19 at 15:04

1 Answers1

1

Your cd command overwrites the contents of root with something else. (check with a debugger!)

I see three options:

  • Switch to using pointers to Folders everywhere. This makes it impossible to accidentally overwrite the folder contents.
  • Rewrite the cd function to use a (maybe global) pointer to "the current directory". This does mean that you have to change all uses of cd.
  • Use std::reference_wrapper for cd, such that current = folder; updates where current points to without changing its contents.
Botje
  • 26,269
  • 3
  • 31
  • 41
  • 1
    Changing `void cd(string name, Folder &current)` to `Folder * cd(string name, Folder &current)` so that you return the new current is safer and more ideologically correct approach to using a global. – user4581301 Jun 07 '19 at 15:09