[C++] Usuwanie wskaźników do obiektów z vector<>

0

Witam.
Mam taki kawałek kodu jak poniżej. Na pierwszy rzut oka wydaje mi się on poprawny lecz ewidentnie coś w nim nie gra (zaznaczyłem to miejsce komentarzem). Przy debugowaniu otrzymuję SIGABRT. Jak poprawić ten kod aby nie dopuszczać do wycieków pamięci oraz żeby wszystko działało poprawnie?

#include <iostream>
#include <vector>

using namespace std;

// ZADANIE 1
class VectorOfIntArray
{
    public:
        VectorOfIntArray() {}

        VectorOfIntArray(VectorOfIntArray& src) {
            //this->~VectorOfIntArray();
            int i = 0;
            while (src.getSize(i) > 0)
            {
                add(src.get(i), src.getSize(i));
                ++i;
            }
        }

        ~VectorOfIntArray() {
            for(int i = 0; i < val.size(); ++i)
            {
                int * tmp = val[i];
                delete[] tmp;         /// TA LINIJKA POWODUJE BŁĄD
            }
            val.clear();
        }

        int * get(int rowidx) {
            if (val.size() <= rowidx)
                return NULL;
            int * tmp = val[rowidx];
            return tmp+1;
        }

        int getSize(int rowidx) {
            if (val.size() <= rowidx)
                return -1;
            int * tmp = val[rowidx];
            return tmp[0];
        }

        void add(int * tab, int size) {
            if (tab && size > 0) {
                int * tmp = new int[size+1];
                tmp[0] = size;
                for (int i = 1; i<=size; ++i)
                    tmp[i] = tab[i-1];
                val.push_back(tmp);
            }
        }

    private:
        vector<int*> val;
};

int main()
{
  // ZADANIE 1
    VectorOfIntArray foo;
    int * tmp1 = new int[10];
    for (int i = 0; i < 10; ++i) tmp1[i] = i;
    foo.add(tmp1, 10);
    int * tmp2 = new int[20];
    for (int i = 0; i < 20; ++i) tmp2[i] = i;
    foo.add(tmp2, 20);
    int * tmp3 = new int[11];
    for (int i = 0; i < 11; ++i) tmp3[i] = i;
    foo.add(tmp3, 11);
    int * tmp4 = new int[14];
    for (int i = 0; i < 14; ++i) tmp4[i] = i;
    foo.add(tmp4, 14);
    {
        VectorOfIntArray * foo2 = new VectorOfIntArray(foo);
        int i = 0;
        while (foo2->getSize(i) > 0) {
            int * tmp = foo2->get(i);
            for (int j = 0; j < foo2->getSize(i); ++j)
                cout << tmp[j] << ",";
            cout << endl;
            ++i;
            tmp1 = tmp;
        }
        delete foo2;        /// TUTAJ WYWOŁUJĘ NIESZCZĘSNY DESTRUKTOR
    }

    return 0;
}
0
int * tmp4 = new int[14];
for (int i = 0; i < 140; ++i) tmp4[i] = i;
foo.add(tmp4, 14);

140? :>

I po co te alokacje? Nie można tak:

int tmp[20];

for (int i = 0; i < 20; ++i) tmp[i] = i;

foo.add(tmp, 10);
foo.add(tmp, 20);
foo.add(tmp, 11);
foo.add(tmp, 14);

???

int getSize(int rowidx)
{
	(...)
	
	int * tmp = val[rowidx];
	if (tmp == 0) return -1; //<--- (1)
	
	(...)
}

int* get(int rowidx) 
{
	(...)
	
	int * tmp = val[rowidx];
	if (tmp == 0) return -1; //<--- (1)
	return tmp;	//<--- (2)
}

void add(int * tab, int size) 
{
	(...)

	for (int i = 1; i<=size; ++i) //<--- (3)
		tmp[i] = tab[i-1];

	(...)

}

(1) nie rozumiem dlaczego dopuszczasz możliwość, że val może zawierać wskaźnik NULL? Taka sytuacja nie powinna się zdarzyć.
(2) pierwszy element to rozmiar tablicy, więc metoda powinna zwrócić wskaźnik na następny element, szczególnie że podajesz go funkcji add w konstruktorze kopiującym.
(3) o memcpy słyszał?

0

(1) Faktycznie niepotrzebne są te linijki
(2) wiem - testowałem i zmieniałem wszystko co się da żeby działało...
(3) słyszał ale to jest zadanie (egzamin/kolokwium) w którym nie można było z tego skorzystać

Alokacje po to że tak miałem postawione w treści zadania. Ma to być vektor zawierający tablice intów dynamicznie alokowane.

🤦 i te całe problemy przy dealokacji pamięci przez to głupie 140 ?????

0

No nie takie głupie - psujesz stertę.

0

prędzej spodziewał bym się czegoś w stylu naruszenia ochrony pamięci niż problemów przy zwalnianiu pamięci. :P
Ale nie ważne. Człowiek uczy się na błędach - teraz będę już wiedział na przyszłość gdzie szukać ewentualnych błędów.

Dzięki za pomoc i sokole oko ;)

0

A tak w sumie to po co się tak przemęczasz? Przecież ewidentnie widać że tobie jest potrzebne coś takiego:

vector<vector<int> >
0

też można tak ale w temacie zadania wyraźnie miałem napisane:
"do wierszy tablicy nie stosować STL tylko dynamicznie generowanych tablic int*"
Niestety takie są uroki programowania na kartkach na ocenę :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1