我最近一直在刷我的C ++,我有一个关于删除新内存的快速问题。正如您在下面看到的,我有一个包含FileData *列表的简单类。我创建了一个数组来保存要推送到列表中的FileData对象。当ReportData被破坏时,我遍历列表并删除每个元素。我的问题是,当我使用reportData时,如何删除数组,以便我没有任何内存泄漏?
class REPORTAPI ReportData {
public:
ReportData()
{
}
virtual ~ReportData()
{
printf("Starting ReportData Delete\n");
for (list<FileData*>::iterator i = ReportFileData.begin(), e = ReportFileData.end(); i != e; )
{
list<FileData*>::iterator tmp(i++);
delete *tmp;
ReportFileData.erase(tmp);
}
for (list<SupressionData*>::iterator i = ReportSupressionData.begin(), e = ReportSupressionData.end(); i != e; )
{
list<SupressionData*>::iterator tmp(i++);
delete *tmp;
ReportSupressionData.erase(tmp);
}
ReportFileData.clear();
ReportSupressionData.clear();
printf("Finished ReportData Delete\n");
}
list<FileData *> ReportFileData;
list<SupressionData *> ReportSupressionData;
}
extern "C" __declspec(dllexport) FileData* __stdcall createFileData(string fileName, long recordCount, long addPageCount)
{
return new FileData(fileName, recordCount, addPageCount);
}
ReportData *reportData = createrd();
if (reportData != NULL)
{
CreateFileDataFunc createfd (reinterpret_cast<CreateFileDataFunc>(GetProcAddress (dll, "createFileData")));
const int num_files = 5;
FileData *fileData[num_files];
char buff[256] = {'\0'};
for (int i = 0; i < num_files; i++)
{
sprintf(buff, "test: %d", i);
fileData[i] = createfd(buff, 1, 1);
reportData->ReportFileData.push_back(fileData[i]);
}
delete reportData;
reportData = NULL;
delete [] fileData; // this is throwing an access violation error:
//EAccessViolation: 'Access violation at address 326025AF. Write of address 00000008'.
}
---我从ReportData dtor中删除了删除操作 我现在正在循环和删除:
for(int i = 0; i < num_files; i++)
{
delete fileData[i];
}
这更容易理解,然后必须依靠单独的对象的dtor来清理内存。
答案 0 :(得分:6)
你没有。 fileData是一个自动(堆栈)变量。你没有用new分配它,所以你不要删除它。
[编辑:我也不确定,但我认为你可能会遇到从main.cpp删除那些FileData对象的问题,因为它们是在某些dll中分配的。 dll是否提供了删除功能?]
答案 1 :(得分:2)
您的数组未动态分配,因此您无需删除它。但是,每个元素都指向一个动态分配的对象(来自您的注释):
createfd是一个函数指针,它通过
返回FileData的新实例
您需要做的是遍历数组的元素,并释放它们中的每一个。
for(int i = 0; i < num_files; i++)
{
delete fileData[i];
}
答案 2 :(得分:0)
// allocate on the stack, no manual delete required
FileData *fileData[num_files];
// allocate on the heap, must delete after usage
FileData *fileData = new FileData[num_files];
// ..
delete [] fileData;
答案 3 :(得分:0)
无需删除或清除两个列表中的任何一个 - 默认析构函数将为您完成此操作。假设列表中包含的指针(到“数组”?我不清楚)已经动态分配,你需要删除它们。但是,您可以(并且应该)通过使列表包含std :: vectors或合适的智能指针来明确地避免这样做。
答案 4 :(得分:0)
“我的问题是,当我使用reportData时,如何删除数组,以便我没有任何内存泄漏?”
这是错误的问题。正确的问题是“谁应该删除这些FileData对象?”,答案是“理想情况下,在这个cae Main.cpp中构建它们的人”。通过报告数据来完成工作是尴尬和不稳定的;完成工作两次(一次在ReportData析构函数中再次在Main.cpp中)会侵犯内存。
如果必须销毁~ReportData()中的对象,则不要在Main.cpp中对它们做任何事情。那么你的代码就是正确的。可怕,但是正确。
答案 5 :(得分:0)
您是否考虑过使用智能指针包装FileData *?
你的dtor的问题是异常会导致内存泄漏(还有一些与dtor漏出的异常相关的其他问题)。
答案 6 :(得分:0)
不要在main()中释放任何内容。
reportData的析构函数将处理使用createfd()分配的所有内容(只需确保createfd()返回它使用new()分配的内容,因为你不能删除任何非new'd的内容。
fileData在堆栈上本地分配,而不是通过new分配。由于它没有被新分配,所以不要删除它。
传递给fileData的指针也传递给reportData,reportData负责那里的所有删除。您可以检查它们是否未从无法访问的内存池中分配(例如在动态链接的库中);如果他们是,这是一个问题。
因此,假设ReportData析构函数中的删除是正确的,删除fileData的任何删除都是正确的。