我有此标头代码
class BaseFile {
private:
std::string name;
public:
BaseFile(string name);
string getName() const;
void setName(string newName);
virtual int getSize() = 0;
};
class File : public BaseFile {
private:
int size;
public:
File(string name, int size); // Constructor
int getSize(); // Return the size of the file
};
class Directory : public BaseFile {
private:
vector<BaseFile*> children;
Directory *parent;
public:
Directory(string name, Directory *parent); // Constructor
virtual ~Directory(); //destructor
Directory *getParent() const; // Return a pointer to the parent of this directory
void setParent(Directory *newParent); // Change the parent of this directory
void addFile(BaseFile* file); // Add the file to children
void removeFile(string name); // Remove the file with the specified name from children
void removeFile(BaseFile* file); // Remove the file from children
void sortByName(); // Sort children by name alphabetically (not recursively)
void sortBySize(); // Sort children by size (not recursively)
vector<BaseFile*> getChildren(); // Return children
int getSize(); // Return the size of the directory (recursively)
string getAbsolutePath(); //Return the path from the root to this
};
我实现了所有方法和析构函数
Directory::~Directory() {
for (int i = 0; i < children.size(); i++){
BaseFile *ptr = children[i];
delete ptr;
}
children.clear();
delete parent;
parent = nullptr;
}
在我的主目录中,我想测试在目录内创建目录 像这样:
int main(int , char **) {
//Environment env;
//env.start();
Directory *d = new Directory("test", nullptr);
Directory *d1 = new Directory("test2" , d);
File *f = new File("test" , 100);
d1->addFile(f);
d->addFile(d1);
delete d;
return 0;
}
我跑步时
valgrind --leak-check=full --show-reachable=yes Assingment1
我在向量中创建文件而导致内存泄漏,而向量在另一个向量中,因此析构函数无法正确删除它。
==20161== HEAP SUMMARY:
==20161== in use at exit: 56 bytes in 2 blocks
==20161== total heap usage: 6 allocs, 4 frees, 72,912 bytes allocated
==20161==
==20161== 48 bytes in 1 blocks are indirectly lost in loss record 1 of 2
==20161== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20161== by 0x10955D: main (Main.cpp:16)
==20161==
==20161== 56 (8 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==20161== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20161== by 0x10D5E9: __gnu_cxx::new_allocator<BaseFile*>::allocate(unsigned long, void const*) (new_allocator.h:111)
==20161== by 0x10D3F4: std::allocator_traits<std::allocator<BaseFile*> >::allocate(std::allocator<BaseFile*>&, unsigned long) (alloc_traits.h:436)
==20161== by 0x10D0BF: std::_Vector_base<BaseFile*, std::allocator<BaseFile*> >::_M_allocate(unsigned long) (stl_vector.h:172)
==20161== by 0x10C8E5: void std::vector<BaseFile*, std::allocator<BaseFile*> >::_M_realloc_insert<BaseFile* const&>(__gnu_cxx::__normal_iterator<BaseFile**, std::vector<BaseFile*, std::allocator<BaseFile*> > >, BaseFile* const&) (vector.tcc:406)
==20161== by 0x10C335: std::vector<BaseFile*, std::allocator<BaseFile*> >::push_back(BaseFile* const&) (stl_vector.h:948)
==20161== by 0x10999E: Directory::addFile(BaseFile*) (Files.cpp:42)
==20161== by 0x10959F: main (Main.cpp:18)
==20161==
==20161== LEAK SUMMARY:
==20161== definitely lost: 8 bytes in 1 blocks
==20161== indirectly lost: 48 bytes in 1 blocks
==20161== possibly lost: 0 bytes in 0 blocks
==20161== still reachable: 0 bytes in 0 blocks
==20161== suppressed: 0 bytes in 0 blocks
==20161==
==20161== For counts of detected and suppressed errors, rerun with: -v
==20161== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
有没有更好的方法来编写析构函数,以便它可以删除向量中的所有文件?
答案 0 :(得分:3)
首先,您的代码在目录的删除语义上似乎不太清楚。应该清楚目录是删除其所有子目录还是子目录删除其父目录。这也需要在复制和移动构造函数/运算符中解决。否则,您将泄漏。
此外,您的代码似乎容易多次删除同一目录。这可能会导致崩溃或不确定的行为。
如果您想改善指针的处理能力,可以从C ++ 11开始使用一种叫做智能指针的好方法。除了使用Directory*
之类的原始指针,您还可以使用例如std::shared_ptr<Directory>
,已重载了operator->
和operator*
,因此它的行为就像代码中的指针一样。
智能指针在许多方面都很方便。例如,当最后一个实例超出范围时,它们将自动保留引用计数并删除其封装的原始指针。这在可能发生泄漏的异常情况下也很好用。另一个好处是您不必担心低级内存处理,而有时间专注于应用程序的较大上下文。
如果您是第一次听说智能指针,请知道有很多类型的指针,适用于各种访问和所有权模式。有关更多信息,请查看the introduction和<memory>
header docs。