Na forum jest wiele wątków w których można przeczytać żeby "w c++ nie używać new / delete" używaj std::vector
Będąc przekorny napisałem sobie klasę do zarządzania pamięcią.
Proszę o sprawdzenie mojego programu, czy w nim zachodzą wycieki pamięci, czy jednak jest pozbawiony wycieku pamięci. W funkcjach "add_line" i "delete_line" tworze tymczasowa tablice o nazwie "tmp_table" i moje pytanie brzmi "Czy destruktor czyści tą zarezerwowaną pamięć?"
Jeżeli są jakieś uwagi dotyczące samej budowy klasy to też o nie poproszę.
aha jeszcze jedna uwaga przy tworzeniu tablicy nie wprowadzajcie dużych wartości ponieważ będzie trzeba tą tablicę wypełnić, poniżej wskazówka
można lub nie to zrobić przy metodach "fill_tab()" i "add_line"
//tmp_table[pos][j] = 0;
//tmp_table[pos][j] = (rand() % 100) + 1; //<-- usun komentarz
cout << "Enter [" << pos << "][" << j << "] value : "; //<-- postaw komentarz
cin >> tmp_table[pos][j]; //<-- postaw komentarz
Listing 1.
//2022 Copyright (©) by nanomrowka20
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <limits>
#include <cmath>
#include <vector>
using namespace std;
class newSpace
{
private:
int ** tab;
int ** tmp_table;
int rowCount; //ilosc wierszy
int colCount; //ilosc kolumn
int pos; //pozycja
public:
newSpace()
{
cout<<"Konstruktor domyslnny bezparametrowy"<<'\n';
//int ** tab = new int*[1]{0}; //Core Dump - Segmentation fault
this->tab = new int*[1]{0};
for(unsigned int i = 0; i < 1; ++i)
tab[i] = new int [1]{0};
this->rowCount = 0;
this->colCount = 0;
}
newSpace(int rowCount, int colCount)
{
if( (rowCount>0) && (colCount>0) )
{
cout<<"Konstruktor domyslnny"<<'\n';
this->tab = new int*[rowCount]{0};
for(int i = 0; i < rowCount; ++i)
tab[i] = new int [colCount]{0};
}
this->rowCount = rowCount;
this->colCount = colCount;
}
void create(int rowCount, int colCount)
{
if( (rowCount>0) && (colCount>0) )
{
cout<<"Konstruktor domyslnny"<<'\n';
this->tab = new int*[rowCount]{0};
for(int i = 0; i < rowCount; ++i)
tab[i] = new int [colCount]{0};
}
this->rowCount = rowCount;
this->colCount = colCount;
}
int add_line(int pos)
{
int iW = rowCount;
int iK = colCount;
//tworzymy nowa tablice o 1 wiersz wieksza
int newSize = iW + 1;
this->tmp_table = new int*[newSize];
for(int i = 0; i < newSize; ++i)
tmp_table[i] = new int [iK];
for(int i = 0, k = 0; i < newSize; ++i)
{
if(i == pos)
{
//cout << "\n";
for(int j = 0, s = 0; j < iK; ++j, ++s)
{
//tmp_table[pos][j] = 0;
//tmp_table[pos][j] = (rand() % 100) + 1;
cout << "Enter [" << pos << "][" << j << "] value : ";
cin >> tmp_table[pos][j];
//cout << "tmp_table["<<pos<<"]["<<j<<"] " << tmp_table[pos][j] << "\n";
}
}
else
{
//cout << "\n";
for(int j = 0, m = i; j < iK; ++j)
{
tmp_table[m][j] = tab[k][j];
//cout << "tmp_table["<<m<<"]["<<j<<"] " << tmp_table[m][j] << " tab["<<k<<"]["<<j<<"] "<< tab[k][j] << "\n";
}
++k;
}
}
rowCount = newSize;
tab = tmp_table;
return this->rowCount;
}
int delete_line(int pos)
{
int iW = rowCount;
int iK = colCount;
//tworzymy nowa tablice o 1 wiersz mniejsza
int newSize = iW - 1;
int ** tmp_table = new int*[newSize];
for(int i = 0; i < newSize; ++i)
tmp_table[i] = new int [iK];
for(int i = 0, k = 0; i < newSize; ++i)
{
if(i == pos)
{
++k;
cout << "\n";
for(int j = 0; j < iK; ++j)
{
tmp_table[pos][j] = tab[k][j];
//cout << "tmp_table["<<pos<<"]["<<j<<"] " << tmp_table[pos][j] << "\ttab["<<k<<"]["<<j<<"] "<< tab[k][j] << "\n";
}
++k;
}
else
{
//cout << "\n";
for(int j = 0; j < iK; ++j)
{
tmp_table[i][j] = tab[k][j];
//cout << "tmp_table["<<i<<"]["<<j<<"] " << tmp_table[i][j] << "\ttab["<<k<<"]["<<j<<"] "<< tab[k][j] << "\n";
}
++k;
}
}
rowCount = newSize;
tab = tmp_table;
return this->rowCount;
}
int size_rowCount()
{
return this->rowCount;
}
int size_colCount()
{
return this->colCount;
}
~newSpace()
{
//Don't forget to delete the array of pointers
for(int i = 0; i < rowCount; ++i)
delete [] tab[i];
delete [] tab;
cout<<"~Destructor"<<'\n';
};
void fill_tab()
{
for(int i = 0; i < rowCount; ++i)
{
for(int j = 0; j < colCount; ++j)
{
//tab[i][j] = (rand() % 100) + 1;
cout << "Enter [" << i << "][" << j << "] value : ";
cin >> tab[i][j];
}
cout << endl;
}
}
void show_me()
{
cout << "\n";
for(int i = 0; i < rowCount; ++i)
{
cout << "Pole position " << i << setw(4) << std::setfill(' ') << right << "\t";
for(int j = 0; j < colCount; ++j)
{
cout << setw(4) << std::setfill(' ') << right << tab[i][j] << " ";
}
cout << "\n";
}
cout << "\n";
}
};
typedef struct
{
int id;
string description;
} Operation;
int check_input();
void clear_input();
int menu();
int main()
{
srand(time(NULL));
int iW{0}, iK{0}; //iW - ilosc wierszy, iK - ilosc kolumn
int pos{0};
newSpace tab;
bool infinity = true;
for(;infinity;)
{
int currentSize = tab.size_rowCount();
int r = menu();
cout << "Select an action : ";
int choice { check_input() };
switch( choice )
{
case 1:
while((cout<<"Ile wierszy : ")&&(cin>>iW)&&(cout<<"Ile kolumn : ")&&(cin>>iK))
{
tab.create(iW,iK);break;
}
break;
case 2:
if( currentSize == 0 )
{
cout << "\n\t\"the array is empty\"\n" << "\n";
break;
} else {
tab.fill_tab();
}
break;
case 3:
if( currentSize == 0 )
{
cout << "\n\t\"the array is empty\"\n" << "\n";
break;
} else {
tab.show_me();
}
break;
case 4:
if( currentSize == 0 )
{
cout << "\n\t\"the array is empty\"\n" << "\n";
break;
} else {
while( (cout << "\nWstaw wiersz na pozycji z zakresu ( " << 0 << " - " << currentSize << " ) : " ) && (!( cin >> pos ) ||( pos < 0 ) ||( pos > currentSize ) ) )
{
clear_input();
continue;
}
tab.add_line(pos);
}
break;
case 5:
if( currentSize == 0 )
{
cout << "\n\t\"the array is empty\"\n" << "\n";
break;
} else {
while( (cout << "\nUsun wiersz na pozycji z zakresu ( " << 0 << " - " << currentSize-1 << " ) : " ) && (!( cin >> pos ) ||( pos < 0 ) ||( pos > currentSize-1 ) ) )
{
clear_input();
continue;
}
tab.delete_line(pos);
}
break;
case 6:
cout << "\n\t\t\tKoniec programu. Bye!\n";
infinity = false;
break;
default:
cout << "\tMozesz wybrac tylko od 1 do " << r << "\n\n";
break;
}
}
return 0;
}
int check_input()
{
int x;
//while (!(cin >> x))
//while (!(cin >> x) || x == 0 )
while (!(cin >> x) || x == 0 || x < 0 )
{
if (cin.fail())
{
cout << "\tWprowadzony znak nie jest cyfra/liczba" << endl;
cout << "\tProsze podac cyfre/liczbe : ";
//czyscimy strumien wejsciowy std::cin
clear_input();
continue;
}
else if( x < 0 )
{
cout << "\tCyfra/Liczba " << x << " jest liczba ujemna" << endl;
cout << "\tProsze podac cyfre/liczbe dosatnia : ";
clear_input();
continue;
}
else
{
cout << "\tNie moze byc " << x << endl;
cout << "\tProsze podac cyfre/liczbe wieksza od ZERO : ";
//czyscimy strumien wejsciowy std::cin
clear_input();
continue;
}
}
return x;
}
void clear_input()
{
cin.clear();
cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
}
int menu()
{
vector < Operation > data = {
{ 1, "Create table" },
{ 2, "Fill table" },
{ 3, "Print table" },
{ 4, "Add line" },
{ 5, "Delete Line" },
{ 6, "End the program" }
};
cout << "Menu : ";
for(const auto & Item: data )
{
cout << "\t" << Item.id << " " << Item.description << endl;
}
int r = data.size();
return r;
}