向量::p ush_back ( A * ) 产生泄漏
vector::push_back ( A * ) creating leaks?
我正在尝试创建一个非常简单的虚拟文件系统(表示为树)(为我的FTP服务器),映射到我真实文件系统上的几个位置。节点由一个 Node 对象表示,该对象在向量中保存指向其内容的指针。
我知道对于每个新对象都有一个删除(调试到 cout),但我从 valgrind 那里得到了一些"绝对丢失"的字节。
我不仅在对象中保存指针,而且在文件系统类中保存指针,并且我在文件系统的析构函数中删除它们,因此 Node 中保存的指针发生的事情应该无关紧要......右?还是我在这里错过了什么?
瓦尔格林德:
==23638== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==23638== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23638== by 0x407786: __gnu_cxx::new_allocator<Node*>::allocate(unsigned long, void const*) (new_allocator.h:104)
==23638== by 0x40733F: std::_Vector_base<Node*, std::allocator<Node*> >::_M_allocate(unsigned long) (stl_vector.h:168)
==23638== by 0x406FEB: _ZNSt6vectorIP4NodeSaIS1_EE19_M_emplace_back_auxIJS1_EEEvDpOT_ (stl_vector.h:404)
==23638== by 0x406F2F: _ZNSt6vectorIP4NodeSaIS1_EE12emplace_backIJS1_EEEvDpOT_ (vector.tcc:101)
==23638== by 0x40404F: std::vector<Node*, std::allocator<Node*> >::push_back(Node*&&) (stl_vector.h:920)
==23638== by 0x402FD1: Directory::addDirectoryNode(Directory*) (Directory.cpp:20)
==23638== by 0x409600: Filesystem::addDirectory(std::string, std::string) (Filesystem.cpp:47)
==23638== by 0x40B519: Configuration::loadPairs(std::basic_ifstream<char, std::char_traits<char> >&) (Configuration.cpp:85)
==23638== by 0x40B85C: Configuration::load(std::string) (Configuration.cpp:103)
==23638== by 0x4081A9: main (main.cpp:41)
我不太确定还有什么有用的。
文件系统.hpp:
class Filesystem
{
public:
Filesystem ( );
~Filesystem ( );
void addDirectory ( string name, string path ); // the first string is the name of the dir in the virtual FS, path is where the directory actually is.
void addFile ( string );
private:
Directory * root;
Directory * pwd;
map <string, Node *> nodes;
};
Filesystem::~Filesystem ( )
{
for ( auto & it : nodes )
{
if ( it.second != NULL )
{
cout << "deleting " << it . second -> getName ( ) << endl;
delete it.second;
}
}
}
class Directory : public Node
{
public:
Directory ( string name, string path, Directory * mum ) : Node ( name, path ) { parent = mum; }; //assigns name and path, should be clear
void addDirectoryNode ( Directory * );
private:
Directory * parent = NULL;
vector <Node *> contents;
};
void Filesystem::addDirectory ( string name, string path )
{
Directory * toAdd = new Directory ( name, path + "/", NULL );
cout << "created " << name << ", path: " << toAdd -> getPath ( ) << endl;
map <string, Node * > newEntries = toAdd -> loadDirectoryContents ( toAdd -> getDirectoryContents ( ) );
nodes . insert ( pair <string, Node * > ( toAdd -> getPath ( ), toAdd ) );
nodes . insert ( newEntries . begin ( ), newEntries . end ( ) );
if ( name == "/" ) // I know that the first directory added will be "/"
root = pwd = toAdd;
else
root -> addDirectoryNode ( toAdd );
}
// reads the content of this directory and returns it in a set, directories will have a "/" appended
set<string> Directory::getDirectoryContents ( ) const
{
DIR * dir;
dirent * currNode;
set<string> names;
dir = opendir ( path . c_str ( ) );
while ( ( currNode = readdir ( dir ) ) )
{
if ( string ( currNode -> d_name ) == "." || string ( currNode -> d_name ) == ".." )
continue;
if ( currNode -> d_type == DT_DIR )
names.insert ( string ( currNode-> d_name ) + "/" ) ;
else if ( currNode -> d_type == DT_REG )
names.insert ( string ( currNode -> d_name ) ) ;
}
closedir ( dir );
return names;
}
// recursively loads the real contents of this directory into the virtual one
map <string, Node * > Directory::loadDirectoryContents ( set <string> names )
{
map <string, Node * > newEntries;
for ( auto & it : names )
{
if ( it [ ( it . length ( ) - 1 ) ], "/" )
{
Directory * newDir = new Directory ( it, path + it, this );
map <string, Node * > newSubEntries = newDir -> loadDirectoryContents ( newDir -> getDirectoryContents ( ) );
contents . push_back ( newDir );
newEntries . insert ( pair <string, Node * > ( path + it, newDir ) );
newEntries . insert ( newSubEntries . begin ( ), newSubEntries . end ( ) );
}
else
{
File * newFile;
contents . push_back ( newFile = new File ( path + it, path ) );
newEntries . insert ( pair <string, Node * > ( it, newFile ) );
}
}
return newEntries;
}
void Directory::addDirectoryNode ( Directory * directory )
{
contents.push_back ( directory );
}
如果 Node 类中没有虚拟析构函数,则通过基类指针删除 Directory 对象是未定义的行为。不会调用 Directory 类的析构函数,也不会调用所包含向量的析构函数。这可能会导致内存泄漏。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- Klocwork Inside的资源泄漏
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- C++功能泄漏内存,我是C++新手,不确定如何解决
- 瓦尔格林德的内存泄漏使用新的
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- 无法找出我的代码中的内存泄漏