Skocz do zawartości

ćwiczenia na wskaźnikach cz.2 ;/


LyanVu

Rekomendowane odpowiedzi

Od razu podam kod:

klasy.h:

class cInt2dArray
{
private:
const static unsigned short DOMYSLNYy = 2;
const static unsigned short DOMYSLNYx = 2;

unsigned muRozmiarY;
unsigned muRozmiarX;
unsigned* puTablica;

public:
cInt2dArray() { muRozmiarY = DOMYSLNYy; muRozmiarX = DOMYSLNYx; puTablica = new unsigned[muRozmiarY * muRozmiarX]; }
cInt2dArray(unsigned uRozmiarY,unsigned uRozmiarX) { muRozmiarY = uRozmiarY; muRozmiarX = uRozmiarX; puTablica = new unsigned[muRozmiarY * muRozmiarX]; }
~cInt2dArray() { delete[] puTablica; }

unsigned GetRozmiarY() { return muRozmiarY; }
unsigned GetRozmiarX() { return muRozmiarX; }
void SetDane(int* nDane, unsigned uIndeks1, unsigned uIndeks2)
{
	puTablica[uIndeks1 * uIndeks2] = *nDane;
}
int GetDane(unsigned uIndeks1, unsigned uIndeks2) { return puTablica[uIndeks1*uIndeks2]; }
bool ChangeRozmiar(unsigned uRozmiarY, unsigned uRozmiarX);
};

main.cpp"

// INCLUDY SĄ PRAWIDŁOWE
bool cInt2dArray::ChangeRozmiar(unsigned uRozmiarY, unsigned uRozmiarX)
{
if (uRozmiarY < 0 || uRozmiarX < 0) return false;
unsigned* puNowaTablica = new unsigned[uRozmiarY *uRozmiarX];
memcpy(puNowaTablica, puTablica, (uRozmiarY*uRozmiarX)*sizeof(unsigned));

delete[] puTablica;
puTablica = puNowaTablica;
delete[] puNowaTablica;

return true;
}

int main()
{

unsigned uRozmiarY, uRozmiarX;
int nDane;

cout << "Podaj Rozmiar Y tablicy: ";
cin >> uRozmiarY;
cout << endl << "Podaj Rozmiar X tablicy: ";
cin >> uRozmiarX;

cInt2dArray* puTablica = new cInt2dArray(uRozmiarY,uRozmiarX);

cout << endl <<  "Podaj Rozmiar Y tablicy: ";
cin >> uRozmiarY;
cout << endl << "Podaj Rozmiar X tablicy: ";
cin >> uRozmiarX;
cout << endl << "Podaj Dane do wprowadzenia: ";
cin >> nDane;
puTablica->SetDane(&nDane, uRozmiarY, uRozmiarX);
cout << endl << "Dane to: " << puTablica->GetDane(uRozmiarY, uRozmiarX);
cout << endl << "Zmieniamy Rozmiar. Rozmiar Y: ";
cin >> uRozmiarY;
cout << endl << "Rozmiar X: ";
cin >> uRozmiarX;
puTablica->ChangeRozmiar(uRozmiarY, uRozmiarX);
cout << endl << "Podaj Rozmiar Y tablicy: ";
cin >> uRozmiarY;
cout << endl << "Podaj Rozmiar X tablicy: ";
cin >> uRozmiarX;
cout <<  endl << puTablica->GetDane(uRozmiarY, uRozmiarX);
_getch();
delete puTablica;


_getch();
return 0;
}

 

No a problem polega na tym, że po prostu wyskakuje coś takiego gdy już zmienię rozmiar tablicy i podaję y,x aby sprawdzic jakies dane ;p

 

PROBLEM

 

#Edit1

Dodam, że umyślnie nie zrobiłem tego na zasadzie unsigned** pTablica :D

Odnośnik do komentarza
Udostępnij na innych stronach

Przybrałeś zły sposób na iterowanie po danych w tablicy, konkretnie chodzi o: puTablica[uIndeks1 * uIndeks2]. Tak nie może być. :)

 

Jeżeli chcesz użyć liniowej metody dostępu do adresu pamięci w postaci 2-wymiarowej tablicy blablabla, musisz daną pozycję Y pomnożyć przez "szerokość" tablicy aby wyznaczyć wiersz, i dodać "przejście" X po komórkach:

puTablica[uIndeksY*muRozmiarX + uIndeksX]

 

Proponuję zmienić konwencję kodowania, gdyż ciężko "to" się czyta... To taka moja luźna propozycja. :)

 

Tak samo jak zasada ze zmiennymi 'n' (ilość), jak i 'i' (pozycja). Z X/Y-ami postępuje się podobnie. X-y podawaj na początku argumentów, Y jako drugi.

 

#EDIT:

Proponuję abyś jeszcze raz zbadał metodę cInt2dArray::ChangeRozmiar, możesz być niemile zaskoczony. Konkretnie chodzi o delete[] puNowaTablica;

Odnośnik do komentarza
Udostępnij na innych stronach

Polski lub angielski, bo u ciebie nazwy metod to setWartość, getWartość, setRozmiar.

Kiedyś zaczniesz się mylić bo nie będziesz pewny czy funkcje zapisałeś jakoś po angielsku, czy po polsku.

Lepiej wybrać sobie jeden język i nim zapisywać nazwy zmiennych, funkcji.

Ja np. ostatnio jak coś kodze, to nazwy danych pisze po angielsku, tylko komentarze są po polsku.

A i wcześniej zdarzało mi się robić tak, jak ty i z czasem musiałem patrzeć np. jak dana zmienna się nazywała,

zamiast pisać od strzała co ma się dziać w programiku.

Odnośnik do komentarza
Udostępnij na innych stronach

#EDIT:

Proponuję abyś jeszcze raz zbadał metodę cInt2dArray::ChangeRozmiar, możesz być niemile zaskoczony. Konkretnie chodzi o delete[] puNowaTablica;

 

Czy chodzi ci o to, że ja wymazuję obszar pamięci gdzie rezyduje tablica? Bo nie jestem pewny czy dobrze pomyślałem :)

 

EDIT - WIN:

 

Udało mi się :) Zaczeło działać kiedy zmieniłem

delete[] puTablica;
puTablica = puNowaTablica;
delete[] puNowaTablica;

Na:

	
puTablica = NULL;
delete[] puTablica;
puTablica = puNowaTablica;
puNowaTablica = NULL;
delete[] puNowaTablica;

 

Tak więc dzięki wszystkim :)

Odnośnik do komentarza
Udostępnij na innych stronach

Czy chodzi ci o to, że ja wymazuję obszar pamięci gdzie rezyduje tablica? Bo nie jestem pewny czy dobrze pomyślałem :) [/size][/i]

 

EDIT - WIN:

 

Udało mi się :) Zaczeło działać kiedy zmieniłem

delete[] puTablica;
puTablica = puNowaTablica;
delete[] puNowaTablica;

Na:

	
puTablica = NULL;
delete[] puTablica;
puTablica = puNowaTablica;
puNowaTablica = NULL;
delete[] puNowaTablica;

 

Tak więc dzięki wszystkim :)

puNowaTablica = NULL;
delete[] puNowaTablica;

Wywal to całkiem. O,o

 

Usuwanie wskaźnika na 'nullptr' nie daje żadnego efektu. Więc ta część kodu w ogóle nie jest potrzebna.

Odnośnik do komentarza
Udostępnij na innych stronach

To zostawić np. chociaż samo puNowaTablica = NULL; ?

Chodzi mi o to, że może nastąpić tzw. Wyciek pamięci, czy nie mam racji?

 

Wyciek pamięci jest wtedy, kiedy masz wskaźnik który alokuje pamięć dla jakiegoś obiektu

np.:

int *pointer = new int(3);

a następnie nie zwolniwszy wcześniej zaalokowanej pamięci przestawiasz wskaźnik na coś innego:

pointer = &obiekt;

Wtedy nie masz jak dostać się już do tego int'a którego zaalokowałeś, no bo nic innego na niego nie wskazuje, a ty się możesz tylko domyślać w której komórce został on utworzony... Konrad-GM ma racje, wskaźniki przestawia się na NULL żeby przypadkiem nie wskazały na coś na co nie powinny + kiedy wskaźnik wskazuje na NULL, to delete nie da żadnego efektu. Ty w swoim kodzie już ustawiłeś inny wskaźnik na odpowiedni adres, więc nadal masz do niego dostęp i w każdej chwili możesz zwolnić ten obszar pamięci, gdyby było inaczej to tak, miałbyś wyciek.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...