Błąd kopiowanie komorki po komorce w tablicy 2 wymiarowej.....?

0

Witajcie

Robię sobie zadanko w którym po podaniu do tablicy 2 wymiarowej danych podaje ktore wiersze maja byc zamienione miejscami. Występuje problem podczas dojścia do próby koiowania tych komorek w funkcji, ale nie wykazuje żadnych error'ow podczas kompilacji. Wiecie dlaczego tak sie dzieje?
Wklejam programik i wszystko sie kompiluje. Proszę o pomoc.

 
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int sum_przek(int **tab,int a)
{
	int i,j;
	int wyn=0;
	int d=1;
	for(i=0;i<a;i++)
	{
		for(j=d;j<a;j++)
		{
			wyn+=tab[i][j];
		}
		d++;
	}
	return wyn;
}
void wczytaj_dane(int **tab,int a,int b)
{
	int i,j;
	for(i=0;i<a;i++)
	{
		for(j=0;j<b;j++)
		{
			printf("Podaj liczbe do wczytania:\n");
			scanf("%d",&tab[i][j]);
		}
	}
	printf("\n");
}
void wypisz(int **tab,int a,int b)
{
	int i,j;
	for(i=0;i<a;i++)
	{
		for(j=0;j<b;j++)
		{
			//printf("\t");
			printf("%3d",tab[i][j]);
		}
		printf("\n");
	}
}
void zam_wiersze(int **tab,int a,int b,int **wsk,int &x1,int &x2)
{
	int i,j;
	for(i=0;i<b;i++)
	{
		wsk[0][i]=tab[x1][i];		//kopiowanie wybranego wiersza
		wsk[1][i]=tab[x2][i];
	}
	for(j=0;j<b;j++)
	{
		//kopiowanie po zamianie
		tab[x1][i]=wsk[1][i];
		tab[x2][i]=wsk[0][i];
	}
	wypisz(tab,a,b);
	printf("\n");
}
int main()
{
	int a,b,i,j,**tab,**wsk,x1,x2;
	int wynik;	//zmienna przechowujaca wartosc sumy prezkatnej
	printf("Podaj wymiar A i B:");
	scanf("%d %d",&a,&b);
	tab=new int*[a];	//tablica 2 wymiarowa
	wsk=new int*[2];		//wzkaznik do tablicy pomocniczej
	for(j=0;j<2;j++)
	{
		wsk[j]=new int[b];
	}
	for(i=0;i<a;i++)
	{
		tab[i]=new int[b];
	}

	wczytaj_dane(tab,a,b);
	wypisz(tab,a,b);
	printf("Podaj ktore wiersze chcesz zamienic:");
	scanf("%d %d",&x1-1,&x2-1);
	printf("\n");
	zam_wiersze(tab,a,b,wsk,x1,x2);
	//wynik=(sum_przek(tab,a));
	//printf("Suma przekatnej wynosi: %d\n",wynik);


	system("pause");
	delete []tab;
	return EXIT_SUCCESS;
}
0

pisze w C i troche c++

0

No dobrze, ale dlaczego tutaj wyskakuje komunikat przerwania?

0

No dobrze, ale dlaczego tutaj wyskakuje komunikat przerwania?

0

No dobrze, ale dlaczego tutaj wyskakuje komunikat przerwania?

0

Mam pytanko.
CO TO MA ZNACZYĆ:
[code]
scanf("%d %d",&x1-1,&x2-1);
[/code]
?
Gdy podajesz do funkcji scanf adres, nie możesz tak tego napisać (chodziło Ci pewnie o zmniejszenie wczytanej wartości o 1 - tak to nie działa - odejmując od "&x1" jedynkę, podajesz po prostu adres czego innego (nie zmiennej x1, lecz czegoś co ma adres o sizeof(int) mniejszy)). Więc musisz skasować to &x1-1, &x2-1 (takim sposobem można coś zniszczyć w pamięci komputera ^^). Ew. dopiero potem odjąć jedynkę od tego:
[code]
scanf("%d %d",&x1,&x2);
x1 -= 1; // Lub x1--
x2 -= 1; //Lub x2--
[/code]
PS
Powinieneś jeszcze poznać biblioteczną funkcję swap z przestrzeni nazw std (czyli: std::swap).
Dostęp do niej możesz uzyskać dołączając plik:
[code]

#include <iostream>

[/code]
Zamienia ona miejscami np. tablice, możesz o niej poczytać sobie gdzieś na forach/stronie C++.
Masz tutaj przykladowe zastosowanie:

 
int** a, **b; 
//Tutaj inicjujesz sobie te tablice i wypełniasz je, np. tak
        for(int i = 0; i < 2; i++) {
            a[i] = new int[3];
            b[i] = new int[3];
        }
        for(int i  = 0; i < 2; i ++)
            for(int j = 0; j < 3; j++) {
                a[i][j] = 10*(j+i);
                b[i][j] = 100*(j+i);
            }
//Albo tak jak to Ty w programie zrobiłeś
//UWAGA! Funkcja std::swap
std::swap(a[1], b[1]);
        for(int i  = 0; i < 2; i ++)
            for(int j = 0; j < 3; j++)
                std::cout << "a[" << i <<"][" << j <<"] = " << a[i][j] <<" ; b[" << i <<"][" << j <<"] = " << b[i][j] << " \n"; 
//Ewidentnie zamienila sie miejscami tablica a[1] (oczywiście z macierzami, czyli a[1][0] zamieniło się z b[1][0], itd.) z tablica b[1]

:-)

0

No dobrze, dzieki za zwrocenie uwagi na ten blad przy SCANF i odpowiedz;)

Ale mam dalej problem. Mógłbyś mi powiedzieć gdzie jest błąd dalej? Dlaczego nie moge poporstu przekopiowac wartosci z jednej do drugiej tabeli a potem po prostu przypisanie jej ponownie do pierwotnej tym prostym sposobem? Dlaczego kompilator sie tutaj ciagle buntuje? Czemu wyskakuje błąd "nieobsluzony wyjatek"?

0

Rozwiązanie 1:
Zamienić po prostu tamtą funkcję na tą:

void zam_wiersze(int **tab,int a,int b,int **wsk,int x1,int x2)
{
        wsk[0] = tab[x1];
        wsk[1] = tab[x2];
        tab[x1] = wsk[1];
        tab[x2] = wsk[0];
        wypisz(tab,a,b);
        printf("\n");
}

Rozwiązanie 2:
Sam myślałem nad tym i dopiero to zauważyłem! hahah ;D
Spójrz na tę pętlę:

        for(j=0;j<b;j++)
        {
                //kopiowanie po zamianie
                tab[x1][i]=wsk[1][i];
                tab[x2][i]=wsk[0][i];
        }

Nie wygląda podejrzanie?
Czyżby zamiast i nie powinno być j?
Tak, glupi blad, tez tego nie widzialem, ale jednak został wykryty.
Jak by co, możesz używać takiego zapisu pętli:

for(int x = 0; x < 100; x++)
//...

co spowoduje że takie błędy raczej nie wystąpią (zmienna jest tylko w obrębie pętli)


Tak więc miałeś 2 błędy, gdyby nie te adresy, to prawdopodobnie tylko jedna zmienna była by dobrze ustawiona (mianowicie x1, ponieważ te zmienne są tworzone na stosie, tak więc prawdopodobnie system przydzieliłby im pamięć "obok siebie", ale mniejsza z tym).
PS
By nie było wycieku powinieneś na końcu jeszcze dodać

delete[] wsk;
0

Hehe, dzięki ci wielkie za ujawnienie tych ukrytych błędów i pomoc w rozwiązaniu problemu;)

0

Hehe, dzięki ci wielkie za ujawnienie tych ukrytych błędów i pomoc w rozwiązaniu problemu;)

0

Hej
Nadal mam problem.......po tej zmianie co podałeś zamieniłem na te J a nie I oraz to twoje "1 rozwiazanie" i nadal komputer siada przy tym. Kompilator się zacina i dalej nie chce ruszyć. Wkleiłem teraz wszystko w Visual'a 2011 z myśla ze moze ta wersja rozwiaze ten problem, ale nic z tego. Mogłbyś zerknąć dlaczego nadal nie idzie z tym?

0

Czy tobie wszystko działa?

0

bez sensu. po co przepisywać? tablica jest alokowana dynamicznie. tab[a] zawiera wskaźnik na wiersz a i tab[b] wskaźnik na wiersz b. jak chcesz zamienić wiersza a i b wystarczy zrobić swapa:

int *temp = tab[a];
tab[a] = tab[b];
tab[b] = temp;
0

@up no wow - wiadomo że ym.. jest to słabe rozwiązanie, ale to był tylko przykładzik, a poza tym nie o tym mowa w temacie..
Tutaj jest działający kod (z twoją funkcją na kopiowanie):

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int sum_przek(int **tab,int a)
{
        int i,j;
        int wyn=0;
        int d=1;
        for(i=0;i<a;i++)
        {
                for(j=d;j<a;j++)
                {
                        wyn+=tab[i][j];
                }
                d++;
        }
        return wyn;
}
void wczytaj_dane(int **tab,int a,int b)
{
        int i,j;
        for(i=0;i<a;i++)
        {
                for(j=0;j<b;j++)
                {
                        printf("Podaj liczbe do wczytania:\n");
                        scanf("%d",&tab[i][j]);
                }
        }
        printf("\n");
}
void wypisz(int **tab,int a,int b)
{
        int i,j;
        for(i=0;i<a;i++)
        {
                for(j=0;j<b;j++)
                {
                        //printf("\t");
                        printf("%3d",tab[i][j]);
                }
                printf("\n");
        }
}
void zam_wiersze(int **tab,int a,int b,int **wsk,int &x1,int &x2)
{
        int i,j;
        for(i=0;i<b;i++)
        {
                wsk[0][i]=tab[x1][i];                //kopiowanie wybranego wiersza
                wsk[1][i]=tab[x2][i];
        }
        for(j=0;j<b;j++)
        {
                //kopiowanie po zamianie
                tab[x1][j]=wsk[1][j];
                tab[x2][j]=wsk[0][j];
        }
        wypisz(tab,a,b);
        printf("\n");
}
int main()
{
        int a,b,i,j,**tab,**wsk,x1,x2;
        int wynik;        //zmienna przechowujaca wartosc sumy prezkatnej
        printf("Podaj wymiar A i B:");
        scanf("%d %d",&a,&b);
        tab=new int*[a];        //tablica 2 wymiarowa
        wsk=new int*[2];                //wzkaznik do tablicy pomocniczej
        for(j=0;j<2;j++)
        {
                wsk[j]=new int[b];
        }
        for(i=0;i<a;i++)
        {
                tab[i]=new int[b];
        }

        wczytaj_dane(tab,a,b);
        wypisz(tab,a,b);
        printf("Podaj ktore wiersze chcesz zamienic:");
        scanf("%d %d",&x1,&x2);
        x1--;
        x2--;
        printf("\n");
        zam_wiersze(tab,a,b,wsk,x1,x2);
        //wynik=(sum_przek(tab,a));
        //printf("Suma przekatnej wynosi: %d\n",wynik);


        system("pause");
        delete[] tab;
        delete[] wsk;
        return EXIT_SUCCESS;
}

Musi działać.. Masz tutaj tekst z konsoli:

Podaj wymiar A i B: 5 5
Podaj liczbe do wczytania:
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 666 19 20 21 22 23 24 25
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:
Podaj liczbe do wczytania:

  1  2  3  4  5
  6  7  8  9 10
 11 12 13 14 15
 16 17666 19 20
 21 22 23 24 25
Podaj ktore wiersze chcesz zamienic: 1 3

 11 12 13 14 15
  6  7  8  9 10
  1  2  3  4  5
 16 17666 19 20
 21 22 23 24 25

Aby kontynuować, naciśnij dowolny klawisz . . .

Wszystko działa ; o

0

Dzieki za pomoc w tej sprawie;)

To może być dziwne lub nie, ale naprawdę mi to nie działało jak poprawiłem to co mi powiedziałeś na samym początku z tym X1 i X2. Poprawiłem i puściłem program żeby mi sie to wykonywało i sie sypało zaraz na początku 1 fora w kopiowaniu wiersza tablicy przed jego zamiana. Teraz skopiowałem to co mi podałeś i jest identyczne poza tymi 2 zmianami na poczatku co wspomniałem i wszystko działa i się nic nie zacina.

Ja nie wiem co jest grane. Czyżby się komputerowi odmieniło? Dodam że próbuję z mnożeniem macierzy i zrobiłem też poprawnie (myśle ze jest w 100% dobrze) a i tak się buntuje i wywala błędy typu że na zakonczenie programu mówi, że jest akurat u mnie "tab3" corrupted kiedy ją wcześniej zwolniłem (tablice) i nie mam już jej w pamięci. Wiecie co jest grane? Tutaj to wypisuje, nie liczby tylko jakieś adresy i nie 1 tablice tylko miesza 1 z 2 tablica (u mnie).

BTW. wrzucam program z macierzami i weź proszę zerknij na co on się teraz obraża, bo ja już nie wiem-.-

Program:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main()
{
	int tab[2][3],tab2[3][2];
	int tab3[2][2];
	int i,j,k;

	for(i=0;i<2;i++)
	{
		for(j=0;j<3;j++)
		{
			scanf("%d",&tab[i][j]);
		}
	}
	printf("DRUGA TABLICA\n\n");

	for(i=0;i<3;i++)
	{
		for(j=0;j<2;j++)
		{
			scanf("%d",&tab[i][j]);
		}
	}

	printf("mnozenie macierzy\n");

	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			for(k=0;k<2;k++)
			{
				tab3[i][j]+=tab[i][k]*tab2[k][j];
			}
		}
	}
	for(i=0;i<2;i++)
	{
		for(j=0;j<2;j++)
		{
			printf("%d",tab3[i][j]);
		}
		printf("\n");
	}
	system("pause");
	delete []tab;
	delete[]tab2;
	delete[] tab3;
	return 0;
}            //tutaj gada że tab3 jest wadliwa-.-
 
0

Noo 'warningi' są dlatego że usuwasz obiekty tworzone na stosie ( int[2][3] ) a nie na stercie( int (*abc)[3] = new int[2][3] ).. Lepiej poczytaj sobie więcej o C++ :>
W tym programie masz wiele błędów..
1:

        printf("DRUGA TABLICA\n\n");
 
        for(i=0;i<3;i++)
        {
                for(j=0;j<2;j++)
                {
                        scanf("%d",&tab[i][j]);
                }
        }

Zamiast 'tab' powinno być 'tab2'
2:

        for(i=0;i<3;i++)
        {
                for(j=0;j<3;j++)
                {
                        for(k=0;k<2;k++)
                        {
                                tab3[i][j]+=tab[i][k]*tab2[k][j];
                        }
                }
        }

Nie rozumiem działania tego programu :D
tab3 powinno chyba tak wyglądać:

int tab3[3][3]; //a nie [2][2]

W sumie tab też powinno wyglądać patrząc na w/w pętlę tak: tab[3][2] .. a patrząc na pierwszą w programie to powinno wyglądać tak: tab[2][3], więc trochę popatrz lepiej na program, masz tu duuużo błędów :((
W sumie już sam nie wiem, nie wiem co chciałeś osiągnąć tym programem ;o
I nie wypisuje on adresów tylko losowe liczby, jak się nie da wartości początkowej albo się ją przekroczy (tak można coś zepsuć) to często mogą się pojawiać ni stąd ni zowąd jakieś liczby
PS
Ja bym Ci polecił używanie funkcji z języka C++, czyli zamiast printf - std::cout, zamiast scanf - std::cin oraz inicjowanie zmiennych w pętli (wygląda bardziej przejrzyście).. lepiej usunąć niektóre nawyki z C

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