[C++] Dwuwymiarowe tablice dynamiczne

Jonarz
Użytkownik
Użytkownik
Posty: 120
Rejestracja: 2 paź 2013, o 22:16
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 32 razy
Pomógł: 11 razy

[C++] Dwuwymiarowe tablice dynamiczne

Post autor: Jonarz »

Próbuję napisać program, który wykonywałby działania na macierzach. Używam funkcji, które później wykorzystuję. Problem polega na tym, że po wpisaniu liczb, program wyświetla losowe wartości w tablicy (jakieś wartości z pamięci). Przypuszczam, że problem jest gdzieś w funkcji wpisywania, ale nie wiem gdzie. Cały kod:

Kod: Zaznacz cały

#include <iostream>
#include <cstdlib>

using namespace std;

void wpis(int **x, int w, int k){
	int i,j;
	x=new int *[w];
	for(i=0;i<w;i++)
		x[i]=new int [k];
	cout<<"Wprowadz liczby do macierzy wierszami:
";
	for(i=0;i<w;i++){
		cout<<">>Wiersz "<<i+1<<".
";
		for(j=0;j<k;j++){
			cout<<"Wprowadz liczbe: ";
			cin>>x[i][j];
		}
	}
}
void druk(int **x, string opis, int w, int k){
	int i,j;
	x=new int *[w];
	for(i=0;i<w;i++)
		x[i]=new int [k];
	cout<<opis<<"
";
	for(i=0;i<w;i++){
		for(j=0;j<k;j++)
			cout<<x[i][j]<<"	";	
		cout<<"
";
	}
}

int main() {
	int **a,w,k,i;
	cout<<"Liczba wierszy macierzy: ";
	cin>>w;
	cout<<"Liczba kolumn macierzy: ";
	cin>>k;
	a=new int *[w];
	for(i=0;i<w;i++)
		a[i]=new int [k];
	wpis(a,w,k);
	druk(a,"Tablica pierwsza: ",w,k);
	cout<<"SPR: "<<a[0][0];
	for(i=0;i<w;i++)
		delete []a[i];
	delete []a;

cout<<"
";
system("PAUSE");
    return EXIT_SUCCESS;
}
Awatar użytkownika
Dasio11
Moderator
Moderator
Posty: 10227
Rejestracja: 21 kwie 2009, o 19:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 40 razy
Pomógł: 2362 razy

[C++] Dwuwymiarowe tablice dynamiczne

Post autor: Dasio11 »

Opiszę, co robi twój kod.

Kod: Zaznacz cały

   a=new int *[w];
   for(i=0;i<w;i++)
      a[i]=new int [k];
Najpierw alokuje pamięć na tablicę dwuwymiarową i umieszcza w a wskaźnik na nią.

Kod: Zaznacz cały

   wpis(a,w,k);

gdzie:

void wpis(int **x, int w, int k){
   int i,j;
   x=new int *[w];
   for(i=0;i<w;i++)
      x[i]=new int [k];
   cout<<"Wprowadz liczby do macierzy wierszami:
";
   for(i=0;i<w;i++){
      cout<<">>Wiersz "<<i+1<<".
";
      for(j=0;j<k;j++){
         cout<<"Wprowadz liczbe: ";
         cin>>x[i][j];
      }
   }
}
Potem przekazuje ten wskaźnik pod nazwą x do funkcji wpis. Ta funkcja ignoruje jednak wartość wskaźnika i zmienną x nadpisuje wskaźnikiem na drugą tablicę, na którą alokowana jest nowa pamięć. Następnie do drugiej tablicy wczytuje od użytkownika dane, a na koniec zapomina wskaźnika do niej. (Przy okazji tworzy się szkodliwy wyciek pamięci)

Kod: Zaznacz cały

   druk(a,"Tablica pierwsza: ",w,k);

gdzie:

void druk(int **x, string opis, int w, int k){
   int i,j;
   x=new int *[w];
   for(i=0;i<w;i++)
      x[i]=new int [k];
   cout<<opis<<"
";
   for(i=0;i<w;i++){
      for(j=0;j<k;j++)
         cout<<x[i][j]<<"	";
      cout<<"
";
   }
}
Dalej, wskaźnik a na pierwszą tablicę jest przekazany pod nazwą x do funkcji druk, która też ignoruje jego wartość i to tej zmiennej zapisuje adres trzeciej tablicy, na którą alokowana jest nowa pamięć. Dalsza część funkcji wyświetla zawartość pamięci trzeciej tablicy, która nie była inicjalizowana, dlatego wychodzą losowe liczby. Na koniec, wskaźnik na trzecią tablicę jest zapominany, co powoduje kolejny wyciek pamięci.

Kod: Zaznacz cały

   cout<<"SPR: "<<a[0][0];
Na koniec, wyświetlana jest wartość pierwszej komórki pierwszej tablicy, która również nie była inicjalizowana. Dlatego najczęściej wyświetli się wartość różna od wpisanej i różna od pierwszego elementu tablicy poprzednio wyświetlonej.


Wniosek: wyrzuć w funkcjach wpis i druk kawałki kodu odpowiedzialne za nadpisywanie przekazanego wskaźnika a i alokację pamięci, to program będzie działać poprawnie.
Jonarz
Użytkownik
Użytkownik
Posty: 120
Rejestracja: 2 paź 2013, o 22:16
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 32 razy
Pomógł: 11 razy

[C++] Dwuwymiarowe tablice dynamiczne

Post autor: Jonarz »

Dziękuję bardzo za pomoc Wzorowałem się na przykładach z wykładów dla funkcji, gdzie nie wykorzystywaliśmy zmiennych dynamicznych, stąd mój brak rozumienia całości działania programu. Dziękuję za dokładne wytłumaczenie, zapamiętam. Program już działa poprawnie.
ODPOWIEDZ