AddTreeNode(tree, foldername, m_ProjectNode, true, FileTreeData::ftdkVirtualFolder, true, vfldIdx, ftd);
I compiled C::B using vs2012, and when I execute the above code, there is a memory leak message when i close C::B.Thanks for the test.
but if i delete the ftd pointer here, it's all OK.
in the function AddTreeNode, it malloc a new FileTreeData and copy the content of this pointer, so there is a memory leak here.Oh, it is definitely a bug here as you said. :)
Revision: b48f1749e8766e286b4d8c908aac933cae1b6ac8
Author: fuscated <fuscated@2a5c6006-c6dd-42ca-98ab-0921f2732cef>
Date: 2013-7-9 7:06:38
Message:
* sdk: Move lots of code related to the projects tree from cbProject to ProjectManagerUI
git-svn-id: http://svn.code.sf.net/p/codeblocks/code/trunk@9194 2a5c6006-c6dd-42ca-98ab-0921f2732cef
----
Modified: src/include/cbproject.h
Modified: src/include/projectfile.h
Modified: src/sdk/cbproject.cpp
Modified: src/src/projectmanagerui.cpp
Modified: src/src/projectmanagerui.h
void ProjectManagerUI::OnAddVirtualFolder(cb_unused wxCommandEvent& event)
{
wxString fld = wxGetTextFromUser(_("Please enter the new virtual folder path:"), _("New virtual folder"));
if (fld.IsEmpty())
return;
wxTreeItemId sel = GetTreeSelection();
if (!sel.IsOk())
return;
FileTreeData* ftd = (FileTreeData*)m_pTree->GetItemData(sel);
if (!ftd)
return;
cbProject* prj = ftd->GetProject();
if (!prj)
return;
ProjectVirtualFolderAdded(prj, m_pTree, sel, fld);
// RebuildTree();
}
BTW: Some one may be interested to see a VC project file for C::B source code, how do you did that? Share it? Thanks.
The main advantage of having this class is that wxTreeItemData objects are destroyed automatically by the tree and, as this class has virtual destructor, it means that the memory and any other resources associated with a tree item will be automatically freed when it is deleted.
the wxTreeItemData object will be destroyed only when it's attached to a FileTreeItem,What do you think does "AddTreeNode(tree, foldername, m_ProjectNode, true, FileTreeData::ftdkVirtualFolder, true, vfldIdx, ftd);" do?
but in the code here, the ftd is not attached to any FileTreeItem, so it will NOT freed automatically.
the wxTreeItemData object will be destroyed only when it's attached to a FileTreeItem,What do you think does "AddTreeNode(tree, foldername, m_ProjectNode, true, FileTreeData::ftdkVirtualFolder, true, vfldIdx, ftd);" do?
but in the code here, the ftd is not attached to any FileTreeItem, so it will NOT freed automatically.
the wxTreeItemData object will be destroyed only when it's attached to a FileTreeItem,What do you think does "AddTreeNode(tree, foldername, m_ProjectNode, true, FileTreeData::ftdkVirtualFolder, true, vfldIdx, ftd);" do?
but in the code here, the ftd is not attached to any FileTreeItem, so it will NOT freed automatically.
wxTreeItemId cbProject::AddTreeNode(wxTreeCtrl* tree,
const wxString& text,
const wxTreeItemId& parent,
bool useFolders,
FileTreeData::FileTreeDataKind folders_kind,
bool compiles,
int image,
FileTreeData* data)
{
// see if the text contains any path info, e.g. plugins/compilergcc/compilergcc.cpp
// in that case, take the first element (plugins in this example), create a sub-folder
// with the same name and recurse with the result...
wxTreeItemId ret;
if (text.IsEmpty())
return ret;
wxString path = text;
// special case for windows and files on a different drive
if ( platform::windows && (path.Length() > 1) && (path.GetChar(1) == _T(':')) )
path.Remove(1, 1);
// avoid empty node names in case of UNC paths, then, at least the first two chars are slashes
while ((path.Length() > 1) && (path.GetChar(0) == _T('\\') || path.GetChar(0) == _T('/')) )
path.Remove(0, 1);
if (path.IsEmpty())
return ret;
int pos = path.Find(_T('/'));
if (pos == -1)
pos = path.Find(_T('\\'));
if (useFolders && pos >= 0)
{
// ok, we got it. now split it up and re-curse
wxString folder = path.Left(pos);
// avoid consecutive path separators
while (path.GetChar(pos + 1) == _T('/') || path.GetChar(pos + 1) == _T('\\'))
++pos;
path = path.Right(path.Length() - pos - 1);
wxTreeItemIdValue cookie = 0;
wxTreeItemId newparent = tree->GetFirstChild(parent, cookie);
while (newparent)
{
wxString itemText = tree->GetItemText(newparent);
if (itemText.Matches(folder))
break;
newparent = tree->GetNextChild(parent, cookie);
}
if (!newparent)
{
// in order not to override wxTreeCtrl to sort alphabetically but the
// folders be always on top, we just search here where to put the new folder...
int fldIdx = Manager::Get()->GetProjectManager()->FolderIconIndex();
int vfldIdx = Manager::Get()->GetProjectManager()->VirtualFolderIconIndex();
newparent = FindNodeToInsertAfter(tree, folder, parent, true);
FileTreeData* ftd = new FileTreeData(*data);
ftd->SetKind(folders_kind);
if (folders_kind != FileTreeData::ftdkVirtualFolder)
ftd->SetFolder(m_CommonTopLevelPath + GetRelativeFolderPath(tree, parent) + folder + wxFILE_SEP_PATH);
else
ftd->SetFolder(GetRelativeFolderPath(tree, parent) + folder + wxFILE_SEP_PATH);
ftd->SetProjectFile(0);
int idx = folders_kind != FileTreeData::ftdkVirtualFolder ? fldIdx : vfldIdx;
newparent = tree->InsertItem(parent, newparent, folder, idx, idx, ftd);
}
ret = AddTreeNode(tree, path, newparent, true, folders_kind, compiles, image, data);
}
else
{
ret = tree->AppendItem(parent, text, image, image, data);
if (!compiles)
tree->SetItemTextColour(ret, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
}
return ret;
}
FileTreeData* ftd = new FileTreeData(*data);
...
newparent = tree->InsertItem(parent, newparent, folder, idx, idx, ftd);
Codeif (text.IsEmpty())
return ret;