2015-11-01 3 views
1

У меня нет ошибок или что-то в этом роде, но проблема в том, что независимо от того, что я делаю, я не могу избавиться от этих утечек памяти. Единственное решение, которое мне удалось найти, это добавить delete[] vector1 после каждого метода, но мне не разрешено изменять эту часть кода. В коде вы можете увидеть комментарии и области, где я могу добавить новые инструкции. Есть ли решение моей проблемы?Проблемы с управлением утечками памяти C++

ЭТО КОД:

#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!"; 
} 
+0

Позволяет ли эта задача изменять поведение (ожидаемый результат) программы, чтобы избавиться от утечек памяти? –

+2

Это домашнее задание, по-видимому, было создано кем-то, кто изучил C++ около 20 лет назад и никогда не удосужился обновить свои знания. –

+0

Я думаю, что знаю, что делать с 'delete [] vector1'. Я попытаюсь, и мой хак скажет вам, удастся ли мне это сделать. –

ответ

0

Для 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: этот хак чувствует себя еще более грязным для меня.
Примечание № 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) 

Edit: я пришел с 3-го (даже грязнее) решения, но я слишком устал от всего этого хакерства, чтобы написать полную версию. Вот пример:

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); 
    // .. 
} 
+0

Что проверяет инструкция if? Вы можете мне это объяснить? Что вы используете для отображения утечек памяти? –

+0

@AlexChihaia Второй раз, когда вы вызываете afisareVector, и в 7-й раз, когда вы вызываете afisareVector, он не может освободить память, во всех других местах он должен это сделать. Я просто добавил статический счетчик, чтобы определить, следует ли вызывать delete []. Постскриптум Я не могу найти хорошую ссылку с объяснением того, как работает статичность. –

+0

@AlexChihaia Если вы хотите объяснить, как работает 'static', я думаю, что [эта ссылка] (http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter10_002.html) даст вам некоторые подсказки. Также обратите внимание: я передумал, что вы должны делать (читайте обновленный ответ). –

0

Я бы сказал, что эта задача невозможно выполнить. Линия

vector1 = readVectorVersion1(&nrElementeVector1); 

Выполняется, когда vector1 содержит динамически выделенный ресурс. Создание неустранимой утечки на этом этапе. То же самое относится и к следующему

readVectorVersion2(&vector1, &nrElementeVector1); 
0

vector1 указатель переписан код, который вы не можете изменить, так ясно, что не может быть только указатель на динамически распределяемой памяти, или же она будет течь, и нет ничего вы можете сделать это, чтобы остановить это, в рамках ограничений вашего задания.

Итак, давайте рассмотрим возможность использования статического объекта для удержания указателя. Я использую std::vector для простоты, но вы можете использовать статический указатель на динамическую память, если хотите. В этом случае вам нужно будет управлять памятью вручную.

int * readVectorVersion1(int * noElements) { 
    static std::vector<int> vector1; 
    vector1.resize(*noElements); 

    // initialize the way you want to 

    return vector1.data(); 
    // return &vector1[0]; // use this if you use older version of c++ than c++11 
} 

И вот вы идете. Память будет освобождена при уничтожении статических объектов. Это, конечно, ограничивает то, что вы можете сделать с функцией. Вы не можете больше выделять два отдельных массива, потому что последующие вызовы будут использовать один и тот же вектор. Но это не нужно для этого задания, поэтому я думаю, это то, о чем просит ваш инструктор.

+0

Хорошо. Я написал этот код, и у меня все еще есть утечки памяти (или, по крайней мере, это вывод). Когда я использую «delete [] vector1» в главном, программа запускается, но я получаю сообщение об ошибке. Что я делаю неправильно? ЭТОТ КОД: –

+0

'#include #include using namespace std; int * readVectorVersion1 (int * noElements) { \t \t статический вектор vector1; \t vector1.resize (* noElements); \t unsigned int i; \t // инициализировать так, как вы хотите \t для (я = 0; я

+0

' void main() { \t int * vector1; \t int nrElem = 4; \t vector1 = readVectorVersion1 (& nRElem); \t afisareVector (vector1, nrElem); \t // delete [] vector1; \t _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE); \t _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDOUT); \t _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE); \t _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDOUT); \t _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE); \t _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDOUT); \t _CrtDumpMemoryLeaks(); } ' –

Смежные вопросы