c++ - 管理内存泄漏 C++ 的问题

标签 c++ memory-leaks

<分区>

我没有得到任何错误或类似的东西,但问题是无论我做什么,我都无法摆脱那些内存泄漏。我发现对我有帮助的唯一解决方案是在每个方法之后添加 delete[] vector1 但我不允许修改那部分代码。 在代码中,您可以看到注释以及我可以添加新指令的区域。我的问题有什么解决方案吗?

这是代码:

#include<iostream>
using namespace std;

/*YOU CAN'T ADD NEW METHODS*/
/*YOU CAN ONLY MODIFY THE BODY OF THE METHODS*/

//read array from the console - number of elements and the elements
int * readVectorVersion1(int * noElements) {
    int *vector1;
    vector1 = new int[*noElements + 1];
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector1[i];

    }
    return vector1;
}
//read array from the console - number of elements and the elements
void readVectorVersion2(int ** vector, int* noElements) {
    *vector = new int[*noElements + 1];
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> (*vector)[i];
    }
}
//read array from the console - number of elements and the elements
void readVectorVersion3(int *& vector, int& noElements) {
    vector = new int[noElements + 1];
    for (int i = 0; i < noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector[i];
    }
}

//read array from the console - number of elements and the elements
int * readVectorVersion4(int& noElements) {
    int *vector1;
    vector1 = new int[noElements + 1];
    for (int i = 0; i < noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector1[i];
    }
    return vector1;
}

//read static array from the console - number of elements and the elements
void readStaticVector(int vector[], int * noElements) {
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector[i];
    }
}

//print the elements of the array
void afisareVector(int* vector, int noElements) {
    cout << endl << "Vector:" << endl;
    for (int i = 0; i < noElements; i++)
        cout << vector[i] << " ";

}


//read a name from the console
char* citesteNume() {
    char temp[200];
    char * nume;
    cout << endl << "Your name:";
    cin >> temp;
    nume = new char[strlen(temp) + 1];
    strcpy(nume, temp);

    return nume;
}

//read a name from the console
void citesteNume(char* nume) {


    cout << endl << "Your name:";
    cin >> nume;


}
//METHODS THAT ADDS AN ELEMENT (THAT IS GIVEN) TO AN EXISTING ARRAY
//FIRST
void adaugaElementNou(int** vector, int* noElemente, int elementNou) {
    (*vector) = new int[*noElemente + 2];
    for (int i = 0; i < *noElemente; i++)
        (*vector)[i] = i;

    (*vector)[*noElemente] = elementNou;

}
//SECOND
int * adaugaElementNou(int& noElemente, int elementNou) {
    int *vector;
    vector = new int[noElemente + 2];
    for (int i = 0; i < noElemente; i++)
        vector[i] = i;
    vector[noElemente] = elementNou;
    return vector;

}
//THIRD
int * adaugaElementNou(int* noElemente, int elementNou) {
    int *vector;
    vector = new int[(*noElemente) + 2];
    for (int i = 0; i < *noElemente; i++)
        vector[i] = i;
    vector[*noElemente] = elementNou;
    return vector;

}



//THE PROGRAM MUST RUN AND NOT GENERATE ANY ERRORS OR MEMORY-LEAKS
void main() {
    //YOU CAN'T ADD NEW VARIABLES

    int * vector1;
    int vector2[50];
    int nrElementeVector1=3;
    int nrElementeVector2=3;

    //YOU CAN ADD NEW INSTRUCTIONS
    // ...
    vector1 = new int[nrElementeVector1 + 1];
    for (int i = 0; i < nrElementeVector1; i++)
        vector1[i] = i;
    for (int i = 0; i < nrElementeVector2; i++)
        vector2[i] = i;
    //YOU CAN'T MODIFY THE FOLLOWING CODE

    afisareVector(vector1, nrElementeVector1);
    afisareVector(vector2, nrElementeVector2);
    //delete[]vector1; /*This instruction is added by me but i`m not allowed to modify this area of the code*/
    vector1 = readVectorVersion1(&nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    //delete[]vector1;
    readVectorVersion2(&vector1, &nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    //delete[]vector1;
    readVectorVersion3(vector1, nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    //delete[]vector1;
    vector1 = readVectorVersion4(nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    //delete[]vector1;
    readStaticVector(vector2, &nrElementeVector2);
    afisareVector(vector2, nrElementeVector2);

    char* string1;
    char string2[50];

    string1 = citesteNume();
    cout << endl << "Hello " << string1;
    //delete[]string1; /*THIS IS NOT ALLOWED HERE*/
    citesteNume(string2);
    cout << endl << "Hello " << string2;

    vector1 = adaugaElementNou(nrElementeVector1, 99);
    afisareVector(vector1, nrElementeVector1+1);
    //delete[]vector1;
    adaugaElementNou(&vector1, &nrElementeVector1, 55);
    afisareVector(vector1, nrElementeVector1+1);
    //delete[]vector1;
    vector1 = adaugaElementNou(&nrElementeVector1, 77);
    afisareVector(vector1, nrElementeVector1+1);
    //delete[]vector1;

    //YOU CAN ADD NEW INSTRUCTIONS HERE
    // ...

    delete[] vector1; //I`ve tried to use delete here because I didn`t knew what else i should do, but I know that it makes no sense(and it`s not working);
    delete[] string1;

    //THE FOLLOWING CODE CHECKS IF THERE ARE ANY MEMORYLEAKS
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
    _CrtDumpMemoryLeaks();

    //YOU CAN'T MODIFY THE FOLLOWING CODE
    vector1 = NULL;
    string1 = NULL;
    cout << endl << "In this moment there are no memory-leaks!";
}

最佳答案

对于 string1 很简单,你可以:

delete[] string1;

这就是我认为你应该对 vector1 做的处理:

void afisareVector(int* vector, int noElements) {
    cout << endl << "Vector:" << endl;
    for (int i = 0; i < noElements; i++)
        cout << vector[i] << " ";

    // A very dirty hack, PLEASE **NEVER** USE IT.
    static int callIndex = 0;
    if(callIndex != 1 && callIndex != 6)
        delete[] vector;
    ++callIndex;
}

valgrind 总结:

==20937== HEAP SUMMARY:
==20937==     in use at exit: 0 bytes in 0 blocks
==20937==   total heap usage: 9 allocs, 9 frees, 144 bytes allocated
==20937== 
==20937== All heap blocks were freed -- no leaks are possible
==20937== 
==20937== For counts of detected and suppressed errors, rerun with: -v
==20937== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

编辑:我改变主意了。上面的例子是你可以做的,这是你应该做的:
注意 #1:这个 hack 对我来说感觉更脏。
注意#2:为了编译它,我必须删除所有 Microsoft 特定的东西并使用 valgrind 执行泄漏检查。

#include<iostream>
#include<cstring>
using namespace std;

/*YOU CAN'T ADD NEW METHODS*/
/*YOU CAN ONLY MODIFY THE BODY OF THE METHODS*/

//read array from the console - number of elements and the elements
int * readVectorVersion1(int * noElements) {
    static int vector1[50];
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector1[i];

    }
    return vector1;
}
//read array from the console - number of elements and the elements
void readVectorVersion2(int ** vector1, int* noElements) {
    static int vector [50];
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector[i];
    }
    *vector1 = vector;
}
//read array from the console - number of elements and the elements
void readVectorVersion3(int *& vector1, int& noElements) {
    static int vector [50];
    for (int i = 0; i < noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector[i];
    }
    vector1 = vector;
}

//read array from the console - number of elements and the elements
int * readVectorVersion4(int& noElements) {
    static int vector1 [50];
    for (int i = 0; i < noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector1[i];
    }
    return vector1;
}

//read static array from the console - number of elements and the elements
void readStaticVector(int vector[], int * noElements) {
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector[i];
    }
}

//print the elements of the array
void afisareVector(int* vector, int noElements) {
    cout << endl << "Vector:" << endl;
    for (int i = 0; i < noElements; i++)
        cout << vector[i] << " ";
}


//read a name from the console
char* citesteNume() {
    char temp[200];
    char * nume;
    cout << endl << "Your name:";
    cin >> temp;
    nume = new char[strlen(temp) + 1];
    strcpy(nume, temp);

    return nume;
}

//read a name from the console
void citesteNume(char* nume) {


    cout << endl << "Your name:";
    cin >> nume;


}
//METHODS THAT ADDS AN ELEMENT (THAT IS GIVEN) TO AN EXISTING ARRAY
//FIRST
void adaugaElementNou(int** vector, int* noElemente, int elementNou) {
    static int vector1 [50];
    for (int i = 0; i < *noElemente; i++)
        vector1[i] = i;

    vector1[*noElemente] = elementNou;
    *vector = vector1;
}
//SECOND
int * adaugaElementNou(int& noElemente, int elementNou) {
    static int vector [50];
    for (int i = 0; i < noElemente; i++)
        vector[i] = i;
    vector[noElemente] = elementNou;
    return vector;
}
//THIRD
int * adaugaElementNou(int* noElemente, int elementNou) {
    static int vector [50];
    for (int i = 0; i < *noElemente; i++)
        vector[i] = i;
    vector[*noElemente] = elementNou;
    return vector;
}



//THE PROGRAM MUST RUN AND NOT GENERATE ANY ERRORS OR MEMORY-LEAKS
int main() {
    //YOU CAN'T ADD NEW VARIABLES

    int * vector1;
    int vector2[50];
    int nrElementeVector1=3;
    int nrElementeVector2=3;

    //YOU CAN ADD NEW INSTRUCTIONS
    for (int i = 0; i < nrElementeVector2; i++)
        vector2[i] = i;
    vector1 = vector2;
    //YOU CAN'T MODIFY THE FOLLOWING CODE

    afisareVector(vector1, nrElementeVector1);
    afisareVector(vector2, nrElementeVector2);
    vector1 = readVectorVersion1(&nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    readVectorVersion2(&vector1, &nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    readVectorVersion3(vector1, nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    vector1 = readVectorVersion4(nrElementeVector1);
    afisareVector(vector1, nrElementeVector1);
    readStaticVector(vector2, &nrElementeVector2);
    afisareVector(vector2, nrElementeVector2);

    char* string1;
    char string2[50];

    string1 = citesteNume();
    cout << endl << "Hello " << string1;
    citesteNume(string2);
    cout << endl << "Hello " << string2;

    vector1 = adaugaElementNou(nrElementeVector1, 99);
    afisareVector(vector1, nrElementeVector1+1);
    adaugaElementNou(&vector1, &nrElementeVector1, 55);
    afisareVector(vector1, nrElementeVector1+1);
    vector1 = adaugaElementNou(&nrElementeVector1, 77);
    afisareVector(vector1, nrElementeVector1+1);

    //YOU CAN ADD NEW INSTRUCTIONS HERE
    // ...

    delete[] string1;

    //YOU CAN'T MODIFY THE FOLLOWING CODE
    vector1 = NULL;
    string1 = NULL;
}

valgrind 输出:

==21224== HEAP SUMMARY:
==21224==     in use at exit: 0 bytes in 0 blocks
==21224==   total heap usage: 1 allocs, 1 frees, 2 bytes allocated
==21224== 
==21224== All heap blocks were freed -- no leaks are possible
==21224== 
==21224== For counts of detected and suppressed errors, rerun with: -v
==21224== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

编辑:我想出了第三个(甚至更肮脏的)解决方案,但我已经厌倦了所有这些黑客攻击,无法编写完整的版本。这是一个例子:

int * readVectorVersion1(int * noElements) {
    static int *vector1 = NULL;
    delete[] vector1;
    if (noElements < 0)
        return NULL;
    vector1 = new int[*noElements + 1];
    for (int i = 0; i < *noElements; i++)
    {
        cout << endl << "Vector1[" << i + 1 << "]=";
        cin >> vector1[i];

    }
    return vector1;
}

// ...

int main() {
    // ...
    // Just before _CrtSetReportMode
    nrElementeVector1 = -1;
    readVectorVersion1(*nrElementeVector1);
    // ..
}

关于c++ - 管理内存泄漏 C++ 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33461372/

相关文章:

ios - 将 View Controller 放入导航堆栈然后弹出不会释放内存并导致内存泄漏

iphone - 为菜鸟提供使用仪器泄漏的建议

c++ - osx - 构建 POCO 库时出现链接错误

c++ - boost::future 和 std::future 的不同行为

c++ - Cereal 不支持原始指针

javascript - jQuery/Sizzle checkContext 内存泄漏

C# Hook vmtable

c++ - 是否可以将基于范围的 for 循环与迭代器范围一起使用?

node.js - expressjs文件下载内存泄漏

java - 关闭 JavaFX 选项卡不会释放内存