Nieprawidłowe zwalnianie pamięci - program.exe has triggered a breakpoint

0

Witam,
Kończę program - kalkulator macierzy. Mam problem. Co robię nie tak w zwalnianiu pamięci w funkcji inverseMatrix?

mtrx inverseMatrix(float **matrix, int n) {
        mtrx resultMatrix;
        int i, j;
        float det = 1 / calcDeterminant(matrix, n);     //oblicz wyznacznik macierzy
        float *temp = malloc((n - 1)*(n - 1)*sizeof(float));    //alokacja pamieci
        float **minor = malloc((n - 1)*sizeof(float));
        resultMatrix = initializeMatrix(n, n);
        for (i = 0; i < n - 1; i++)
                minor[i] = temp + (i*(n - 1));
        for (j = 0; j < n; j++) {
                for (i = 0; i < n; i++) {
                        //oblicz dopelnienie algebraiczne z matrix(j,i)
                        getMinor(matrix, minor, j, i, n);
                        resultMatrix.array[i][j] = det*calcDeterminant(minor, n - 1);
                        if ((i + j) % 2 == 1)
                                resultMatrix.array[i][j] = -resultMatrix.array[i][j]; //*(-1)^i+j
                }
        }
       
        free(temp); //zwolnienie pamieci
        for (i = 0; i < n - 1; i++) { //bez tej pętli są wycieki pamięci
                free(minor[i]); //zwolnienie pamieci - TUTAJ BŁĄD: PROGRAM.EXE HAS TRIGGERED A BREAKPOINT
        }
        free(minor);
        return resultMatrix;
}


//typ mtrx mam zdefiniowany tak:
//typ strukturalny macierzy
typedef struct {
	int rows, columns; //liczba wierszy i kolumn
	float **array; //tablica dwuwymiarowa dynamiczna
} mtrx;

Oto kod funkcji getMinor i calcDeterminant (obie są poprawne i nie tworzą wycieków pamięci; podobnie jak initializeMatrix i destroyMatrix, odpalane po wyjściu z podglądu wyniku - kiedy to resultMatrix jest kasowana): http://pastebin.com/jHTjCLbb
Z góry wielkie dzięki za pomoc. Męczę się z tym już długo i nie wiem, co robię źle...

0

To co przydzieliłeś - to zwalniaj.
Przydzieliłeś tylko to:

        float *temp = malloc((n - 1)*(n - 1)*sizeof(float));    //alokacja pamieci
        float **minor = malloc((n - 1)*sizeof(float));
0

No tak, właśnie - no to zwalniam:

  free(temp); //zwalniam tempa... - tu na pewno jest wszystko dobrze

Hmm, rozumiem, że chcę zwolnić coś, czego nie ma. Tyle że jak zostawiam samo free(minor), to są wtedy wycieki pamięci... Można prosić o jakąś wskazówkę pomocniczą?

0

Którego słowa nie rozumiesz w zdaniu: - "To co przydzieliłeś - to zwalniaj." ?

        free(temp); //zwolnienie pamieci
        free(minor);
0

No to rozumiem, tylko problem jest taki, że powstają wycieki pamięci i są one na pewno związane z funkcją inverseMatrix, prawdopodobnie z minorem. Nie występują nigdy, gdy np. policzę wyznacznik za pomocą funkcji calcDeterminant, która korzysta z getMinor. Tylko wtedy, gdy odpalę inverseMatrix.

Detected memory leaks!
Dumping objects ->
e:\dropbox\studia\programowanie komputerów\sem 2 - lab\proj-macierze\proj-macierze\calc.c(12) : {221} normal block at 0x00FCAA28, 16 bytes long.
 Data: <ZLg@   ? YL     > 5A 4C 67 40 8B E9 AC 3F D3 59 4C C0 A6 B3 18 BF 
e:\dropbox\studia\programowanie komputerów\sem 2 - lab\proj-macierze\proj-macierze\calc.c(12) : {220} normal block at 0x00FCA9D8, 16 bytes long.
 Data: <g1  - 3 Lg ?2 E>> 67 31 9D BF 2D A6 33 BF 4C 67 B1 3F 32 9D 45 3E 
e:\dropbox\studia\programowanie komputerów\sem 2 - lab\proj-macierze\proj-macierze\calc.c(12) : {219} normal block at 0x00FCA988, 16 bytes long.
 Data: <$   ? {>$   $   > 24 B8 8F BD 3F 82 7B 3E 24 B8 0F BD 24 B8 8F BC 
e:\dropbox\studia\programowanie komputerów\sem 2 - lab\proj-macierze\proj-macierze\calc.c(12) : {218} normal block at 0x00FCA938, 16 bytes long.
 Data: <  < 6   ( !>(  => AF A1 3C BE 36 94 D7 BD 28 AF 21 3E 28 AF A1 3D 
e:\dropbox\studia\programowanie komputerów\sem 2 - lab\proj-macierze\proj-macierze\calc.c(10) : {217} normal block at 0x00FCA8E8, 16 bytes long.
 Data: <8           (   > 38 A9 FC 00 88 A9 FC 00 D8 A9 FC 00 28 AA FC 00 
Object dump complete.
The program '[6644] proj-macierze.exe' has exited with code 0 (0x0).

12 i 10 linijki w calc.c to linijki funkcji zaalokowania pamięci dla macierzy. Na 100% poprawne, bo wszędzie korzystam z tych funkcji, zarówno initializeMatrix, jak i destroyMatrix, i nigdzie tego problemu nie ma.

1

Jeżeli masz te dwa razy free() to na 100% wyciek nie tu.

0

Dzięki za posta. Hmm, skoro tak piszesz, to jest bardzo niedobrze.
Visual Studio ciągle mówi, że jest parę wycieków, za każdym razem, gdy tylko odpalę odwracanie macierzy...
Szukam czegoś innego, ale nie ma niczego innego, co mogłoby te wycieki powodować prócz jednej z tych 3 funkcji...
Oto pełny kod: [usunąłem, już jest niepotrzebny]
Czy ktoś mógłby mi pomóc odszukać błędy związane z pamięcią? Z góry bardzo dziękuję za znalezienie czegokolwiek, co mogłoby powodować te wycieki.

Żeby uściślić: wycieki występują tylko wtedy, gdy macierz zostanie odwrócona (gdy wyznacznik będzie równy 0, to wycieków nie ma). To nakierowuje jedynie na funkcję inverseMatrix(), po prostu nie ma innej opcji. Co ciekawe, gdy macierz będzie 1x1 i zostanie odwrócona, to również są dwa wycieki pamięci. Grzebię dalej...</del>

EDIT: Okej, mam! Błąd był w innej funkcji, wywołującej inverseMatrix(). Niechcący robiło obliczenia w pętli:

//wyswietlanie wyniku odwracania macierzy
void inversingMatrix(mtrx matrix) {
	int i, det=0;
	char selectionKey;
	mtrx resultMatrix = { 0, 0, NULL };
	det = calcDeterminant(matrix.array, matrix.columns);
	if (det != 0) {
		if (matrix.columns == 1) {
			resultMatrix = initializeMatrix(1, 1);
			resultMatrix.array[0][0] = 1 / matrix.array[0][0];
		}
		else {
			resultMatrix = inverseMatrix(matrix.array, matrix.columns);
		}

	}
	do {  
                //wcześniej niechcący powyższy kod był tutaj
		system("cls");
		printf("\n# ODWRACANIE MACIERZY\n\n");
		for (i = 0; i < (8 * matrix.columns); i++) {
			printf(" ");
		}
		printf("-1\n");
		showMatrix(matrix, "-");
		for (i = 0; i < (8 * matrix.columns - 1); i++) {
			printf(" ");
		}
		printf("=\n\n");
		if (resultMatrix.array != NULL) {
			showMatrix(resultMatrix, "-");//wyswietlenie macierzy bez tytulu
		}
		else {
			printf("Nie mozna odwrocic macierzy - jej wyznacznik jest rowny 0\n");
		}

		printf("\nS. Zapisywanie macierzy wynikowej do pliku\n");
		printf("Q. Powrot do glownego menu\n\n");
		selectionKey = getchar();
		if ((selectionKey == 'S') || (selectionKey == 's')) {
			saveMatrixToFile(resultMatrix);
		}
	} while ((selectionKey != 'Q') && (selectionKey != 'q'));
	destroyMatrix(resultMatrix);
}

Dzięki wielkie @_13th_Dragon za pomoc.

0
_13th_Dragon napisał(a):

Którego słowa nie rozumiesz w zdaniu: - "To co przydzieliłeś - to zwalniaj." ?

        free(temp); //zwolnienie pamieci
        free(minor);

Nie rozumiem skąd w programistach na forach tyle frustracji... nie odzywaj się w ogóle jak nie czujesz takiej potrzeby czlowieku

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