簡體   English   中英

內存堆和泄漏總結

[英]Memmory heap and leak summary

我正在通過矩陣提交我的學校研討會,並且收到有關 memory 泄漏的警告,但是,當我編譯它並通過 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

這是代碼本身:

學校.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;
    }

}

主題.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 之后,我一直得到相同的堆摘要,但現在它實際上說一切都很好,但因為它我無法提交它,因為我的 output 和 output 來自提交矩陣腳本不符合。 有沒有辦法以某種方式關閉它?

------------------------
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或類似的指針。 它應該只是一個愚蠢的 ol' 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

關於跟蹤和避免 memory 泄漏的思考過程(原始答案)

報告說丟失了一個 200 字節的塊。 您可以查看代碼中分配 200 字節的位置並進行更仔細的調查。 例如,如果int為 32 位, Sch.m_noOfSubjects = new int[50]; 適合賬單 32 位 = 4 字節。 4*50 = 200。

讓我們跟蹤m_noOfSubjects並確保它得到正確管理。

一個CTRL + F稍后...

果然,我在給定代碼的任何地方都找不到m_noOfSubjectsdelete

我們如何解決這個問題? std::vector<int>應該是 go 來處理這樣的問題。 vector為您處理從分配到解除分配的所有資源管理,並同時正確處理復制和分配。

也就是說,我懷疑這個作業應該教給你的是RAII 在這種情況下,您要做的是向School class 添加構造函數和析構函數(以及復制構造函數和賦值運算符,因為如果需要析構函數,幾乎總是需要特殊代碼來處理復制)。 不要將School的資源分配在一些免費的read中,這對School class 的健康和福祉毫不在意。 School應該通過在其構造函數或自己的輸入法中分配存儲來照顧自己。 之后,析構函數保證一旦School離開 scope,就會釋放School的所有資源。 您所要做的就是確保School走出 scope。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM