我正在通过矩阵提交学校研讨会,并且收到有关内存泄漏的警告,但是,当我编译它并通过g++命令或VS运行时,它不会显示任何警告或错误。

那是提交的开始

Checking due date:
ON TIME.

Compiling:
g++ -Wall -std=c++11 -o ws utils.o School.cpp schoolTester.cpp Subject.cpp utils.cpp 2> errors.txt

Compile result:
Success! no errors or warnings...

Testing execution:
READ THE FOLLOWING CAREFULLY!
I am about to execute the tester and capture the output in "student_output.txt"
Please enter the values carefuly and exactly as instructed.
Press <ENTER> to start...
Script started, file is student_output.txt
==203824== Memcheck, a memory error detector
==203824== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==203824== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==203824== Command: ws
==203824==
Begin Testing the Program!
--------------------------

Please enter the name of the school:
>

当我运行代码时,我得到此摘要
------------------------
End Testing the Program!
==209192==
==209192== HEAP SUMMARY:
==209192==     in use at exit: 200 bytes in 1 blocks
==209192==   total heap usage: 9 allocs, 8 frees, 366 bytes allocated
==209192==
==209192== LEAK SUMMARY:
==209192==    definitely lost: 200 bytes in 1 blocks
==209192==    indirectly lost: 0 bytes in 0 blocks
==209192==      possibly lost: 0 bytes in 0 blocks
==209192==    still reachable: 0 bytes in 0 blocks
==209192==         suppressed: 0 bytes in 0 blocks
==209192== Rerun with --leak-check=full to see details of leaked memory
==209192==
==209192== For counts of detected and suppressed errors, rerun with: -v
==209192== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Script done, file is student_output.txt

这是代码本身:

School.cpp
namespace sdds {

    School Sch;
    Subject Sub[5];

    void read(School& Sch) {
        Sch.m_name = new char[30];
        char name [61];
        cout << "Please enter the name of the school:\n> ";
        read( name, 61, "Name is too long, only 60 characters allowed!\nRedo Entry: ");

        strcpy(Sch.m_name, name);
        cout << "Please enter the number of subjects offered by " << Sch.m_name << ": ";
        Sch.m_noOfSubjects = new int[50];
        read(*Sch.m_noOfSubjects, 2, 50, "Invalid Number of subjects, 2<=ENTRY<=50\nRedo Entry: ");
        Sch.m_subjects = new int[*Sch.m_noOfSubjects];

        for (int i = 0; i < *Sch.m_noOfSubjects; i++) {
            cout << i+1 << ") ------------------------------" << endl;
            read(Sub[i]);


        }
    }

    int report(const School&Sch) {
        int totalEnr = 0;

        cout << Sch.m_name<<endl;
        cout << "Subject Enrollments" << endl;

        for (int i = 0; i < *Sch.m_noOfSubjects; i++) {
            totalEnr += report(Sub[i]);



        }
        cout << "Total enrollment: " << totalEnr;
        return totalEnr;
    }

    void freeMem(School& Sch) {

        delete [] Sch.m_name;
        Sch.m_name = NULL;

        for (int i = 0; i < *Sch.m_noOfSubjects; i++) {
            freeMem (Sub[i]);
        }

        delete [] Sch.m_subjects;
        Sch.m_subjects = NULL;
    }

}

Subject.cpp
namespace sdds {






    void read(char* str) {

        cout << "Enter subject name: ";

        read(str, 71, "Name is too long, only 70 characters allowed!\nRedo Entry : ");

    }

    void read(int& noofSections) {

        cout << "Enter number of sections: ";

        read(noofSections, 0, 11, "Invalid Number of sections, 1<=ENTRY<=10\nRedo Entry: ");

    }

    void read(int noOfStdsInSecs[], int noOfSections) {
                cout << "Enter the number of students in each one of the " << noOfSections << " sections:" << endl;


        for (int i = 0; i < noOfSections; i++) {

            cout << i+1 << ": ";
            read(noOfStdsInSecs[i], 5, 35, "Invalid Number of students, 5<=ENTRY<=35\nRedo Entry: ");

        }


    }

    void read(Subject& Sub) {


        char subjectName[71];
        read(subjectName);
        Sub.m_subjectName = new char[50];
        strcpy(Sub.m_subjectName, subjectName);

        Sub.m_noOfSections = new int;
        read(*Sub.m_noOfSections);


        Sub.m_noOfStdsInSecs = new int [*Sub.m_noOfSections];
        read(Sub.m_noOfStdsInSecs, *Sub.m_noOfSections);

    }

void freeMem(Subject& Sub) {

        delete[] Sub.m_subjectName;
        Sub.m_subjectName = NULL;
        delete Sub.m_noOfSections;
        Sub.m_noOfSections = NULL;
        delete [] Sub.m_noOfStdsInSecs;
        Sub.m_noOfStdsInSecs = NULL;

    }

更新:
将Sch.m_noOfSubjects转换为int之后,我会继续获得相同的堆摘要,但是现在它从字面上说一切都很好,但是因为它,我无法提交它,因为我的输出和提交矩阵脚本的输出都没有比赛。有办法关闭它吗?
------------------------
End Testing the Program!
==1821==
==1821== HEAP SUMMARY:
==1821==     in use at exit: 0 bytes in 0 blocks
==1821==   total heap usage: 8 allocs, 8 frees, 166 bytes allocated
==1821==
==1821== All heap blocks were freed -- no leaks are possible
==1821==
==1821== For counts of detected and suppressed errors, rerun with: -v
==1821== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Script done, file is student_output.txt

Checking output:
In line number 33 of your output:
The output should be:

^
But your output is:
[38;5;9m------------------------
^

最佳答案

泄漏只是杂耍

完全没有泄漏。正确的事物被释放,而错误在于一件事情被不必要地分配。

查看分配数组后如何使用m_noOfSubjects:

read(*Sch.m_noOfSubjects, 2, 50, "Invalid Number of subjects, 2<=ENTRY<=50\nRedo Entry: ");


Sch.m_subjects = new int[*Sch.m_noOfSubjects];


for (int i = 0; i < *Sch.m_noOfSubjects; i++)

所有人都使用一个值:第一个。这不是数组的行为。这是单个int的行为。
m_noOfSubjects不应是数组或int或类似的指针。它应该只是一个愚蠢的int

School的定义中,替换
int * m_noOfSubjects;


int m_noOfSubjects;

然后删除分配
Sch.m_noOfSubjects = new int[50];

最后消除所有取消引用。例如
read(*Sch.m_noOfSubjects, 2, 50, "Invalid Number of subjects, 2<=ENTRY<=50\nRedo Entry: ");
     ^ remove


Sch.m_subjects = new int[*Sch.m_noOfSubjects];
                         ^ remove


for (int i = 0; i < *Sch.m_noOfSubjects; i++)
                    ^ remove

关于跟踪和避免内存泄漏的思考过程(原始答案)

报告说丢失了一个200字节的块。您可以在代码中查找分配200个字节的位置,并进行更仔细的研究。例如,如果int是32位,则Sch.m_noOfSubjects = new int[50];适合账单32位= 4字节。 4 * 50 = 200。

让我们按照m_noOfSubjects进行操作,并确保对其进行了正确的管理。

一个CTRL + F之后...

果然我在给定代码的任何地方都找不到deletem_noOfSubjects

我们该如何解决? std::vector<int> 应该是处理类似问题的方法。 vector负责从分配到取消分配的所有资源管理,并同时正确处理复制和分配。

就是说,我怀疑这个作业应该教给你的是RAII。在这种情况下,您想要做的是向School类添加一个构造函数和一个析构函数(以及一个复制构造函数和一个赋值运算符,因为if you need a destructor, you almost always need special code to handle copying)。不要在一些School free函数中分配read的资源,这些函数不会对School类的健康产生影响。 School应该通过在其构造函数或自己的输入方法中分配存储空间来寻找自己。后来,析构函数保证School超出范围后,将释放School的所有资源。您所要做的就是确保School超出范围。

关于c++ - 内存堆和泄漏摘要,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58020374/

10-12 16:00