如何删除指针数组

时间:2009-06-23 16:07:48

标签: c++ memory

我最近一直在刷我的C ++,我有一个关于删除新内存的快速问题。正如您在下面看到的,我有一个包含FileData *列表的简单类。我创建了一个数组来保存要推送到列表中的FileData对象。当ReportData被破坏时,我遍历列表并删除每个元素。我的问题是,当我使用reportData时,如何删除数组,以便我没有任何内存泄漏?

Report.h

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);
}

Main.cpp的

        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来清理内存。

7 个答案:

答案 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的任何删除都是正确的。