Problem:
I am writing a simple file manager application. In this program I have a "Directory" class:
class Directory
{
public:
Directory(string address, string directoryname)
{
this->path = address;
this->name = directoryname;
}
string GetFullPath(){ return path == "/" ? path + name : path + "/" + name; }
string path;
string name;
string user;
};
and a linked-list of directory objects:
list<Directory*> DirectoryList;
I want to implement the "rm -r directorypath" shell command in linux, so I need to browse through the list and remove the "directorypath" directory and all of its sub-directories. The problem is that I don't know how to browse through the link list and remove all directories whose parent directory is "directorypath". I have tried these two methods:
method 1:
This method encounters a runtime error, because it cannot access the list anymore after the first deletion.
for (auto address : DirectoryList)
if (address->GetFullPath() == directorypath)
{
for (auto subdirectory : DirectoryList)
if (subdirectory ->path == address->GetFullPath())
DirectoryList.remove(subdirectory );
}
method 2:
for (auto address : DirectoryList)
if (address->GetFullPath() == directorypath)
{
for (auto it = DirectoryList.begin(); it != DirectoryList.end();)
it = DirectoryList.erase(it);
return true;
}
this method can access all the elements perfectly even after deletion but I don't know how to check this if condition using the iterator it:
if (subdirectory ->path == address->GetFullPath())
Your method 1 is failing because std::list.remove(val) removes all elements in your list that compare equal to val. You call it once and you're done. The for() loop shouldn't be there, it's not the way it's intended to be used. Good example is here.
Note that this method will modify your container and the size of it. You need to be careful here and make sure that the your iterators are still valid after calling erase. My gut feeling is that indeed the iterators get invalided and that's why you're getting errors.
Your method 2 looks almost fine. First of all, fallow niceguy's advice to check the condition:
if ((*it).path == address->GetFullPath())
Now, bear in mind that erasing it will update the iterator to point to the location after the iterator you removed. This counts as one update to your iterator, it. It will be further updated in the for loop, but that's not something that you want (i.e. two updates per iteration mean that you're skipping some elements). You could try something like this instead:
auto it = DirectoryList.begin()
while (it != DirectoryList.end())
{
if ((*it).path == address->GetFullPath())
DirectoryList.erase(it);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With