Zwolnienie pamięci macierzy struktur

0

Witam!
Stworzyłem macierz struktur, alokowałem do niej pamięć (struktura przechowuje piksele 3 kolorów <rgb> z obrazka bmp). O ile wiem jak zwolnić pamięć ze zmiennej typu np. int, char, itd. To mam problem jak potraktować strukturę przy zwalnianiu. Czy tak jak normalną zmienną (bez uwzględniania zmiennych wewnątrz struktury, czy zwolnienie struktury należy rozpatrywać pod względem każdej znajdującej się tam zmiennej?

Np.

void AlokacjaPamieciwys(struct Kolory ***colors, struct Odczytuje odczytywanie){
        int i;
        struct Kolory **tmp = NULL;
        tmp = (struct Kolory**)malloc(odczytywanie.szerokosc[0] * sizeof(struct Kolory*));
        for (i = 0; i< odczytywanie.wysokosc[0]; i++)
        {
                (*(tmp + i)) = (struct Kolory*)malloc(1 + odczytywanie.wysokosc[0] * sizeof(struct Kolory));
                if (tmp[i] == NULL)
                {
                        printf("Nie przydziela wartosci");
                }
        }
        *colors = tmp;
}

I tu zwalnianie (koncepcja 1, najbardziej wydaje mi się logiczna, ale wyrzuca mi błąd przy kompilacji):

for(i=0;i<odczytywanie.wysokosc[0];i++) {
  free(colors[i]);
  }
	free(colors);
1

Koncepcja wygląda ok, wklej błąd kompilacji i kod w linijce, której dotyczy.

To mam problem jak potraktować strukturę przy zwalnianiu. Czy tak jak normalną zmienną (bez uwzględniania zmiennych wewnątrz struktury, czy zwolnienie struktury należy rozpatrywać pod względem każdej znajdującej się tam zmiennej?
Jeśli masz tam wskaźnik do dynamicznie zaalokowanej pamięci, którą sam zaalokowałeś, to sam musisz też zwolnić. Jeśli nie to możesz traktować strukturę jak zwykłą zmienną.

0

W załączniku printscreen. Podkreśliłem i=0, znaczy, że nie przechodzi ani razu dokładnie w momencie zwalniania pamięci. Pamięć jest przydzielona prawidłowo...

0

Najpierw mówisz, że jest błąd kompilacji, a teraz pokazujesz, że program działa, tylko... właśnie co? Doszedł do breakpointu?
Z braku kodu wróżę, że colors nie jest tym czym myślisz że jest.

BTW masz pod koniec dwa razy free(colors).

0

Zmienne w strukturze normalnie mają wartość. C

Z braku kodu wróżę, że colors nie jest tym czym myślisz że jest.

Nie rozumiem..
Usunąłem już:

free(colors)

Mógłbyś rzucić okiem w takim razie (kod niepełny, nie ma tu zapełniania pamięci zmiennymi, ale normalnie te zmienne się pojawiają, z alokacją wszystko ok)

struct Kolory
{
	unsigned char blue;
	unsigned char green;
	unsigned char red;

void AlokacjaPamieciwys(struct Kolory ***colors, struct Odczytuje odczytywanie){
	int i;
	struct Kolory **tmp = NULL;
	tmp = (struct Kolory**)malloc(odczytywanie.szerokosc[0] * sizeof(struct Kolory*));
	for (i = 0; i< odczytywanie.wysokosc[0]; i++)
	{
		(*(tmp + i)) = (struct Kolory*)malloc(1 + odczytywanie.wysokosc[0] * sizeof(struct Kolory));
		if (tmp[i] == NULL)
		{
			printf("Nie przydziela wartosci");
		}
	}
	*colors = tmp;


}


int main(){
	int zad, i = 0, j;
 	struct Odczytuje odczytywanie;
	struct Kolory **colors = NULL;


	if (odczytywanie.szerokosc[0] % 4 != 0){			//padding
		odczytywanie.szerokosc[0] = odczytywanie.szerokosc[0] + 4 - (odczytywanie.szerokosc[0] % 4);
	}


	AlokacjaPamieciwys(&colors, odczytywanie);

		OdczytywanieKolorow(&colors, odczytywanie, f1);
		for (i = 0; i < odczytywanie.wysokosc[0]; i++)
		{
			printf(" %d ", colors[i][111].blue);
		}


EDIT: Dochodzi dokładnie do tego miejsca jak ustawiam tam breakpoint

0

Może lepiej wklej cały kod, bo to co wklejasz nawet się nie kompiluje (gdzie jest klamra zamykająca struct Kolory?).

0

Tutaj cały kod (wersja edytowana - poprawiona):

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <locale.h>
#include <string.h>
#include <ctype.h>
#include <windows.h>
#include <math.h>

FILE *f1, *picture;
struct Odczytuje
{
	char Bitmapa[2];
	int rozmiar[1];
	int szerokosc[1];
	int wysokosc[1];
	short int planes[1];
	int reserved1[1];
	int reserved2[1];
	int reserved3[1];
	int BitCount[1];
	int Compresion[1];
	int ImageSize[1];
	int XPixel[1];
	int YPixel[1];
	int ColorsUsed[1];
	int ColorsImportant[1];
	char tempr[2];

};
struct Kolory
{
	unsigned char blue;
	unsigned char green;
	unsigned char red;
};
//progowanie
void AlokacjaPamieciwys(struct Kolory ***colors, struct Odczytuje odczytywanie){
	int i;
	struct Kolory **tmp = NULL;
	tmp = (struct Kolory**)malloc(odczytywanie.szerokosc[0] * sizeof(struct Kolory*));
	for (i = 0; i< odczytywanie.wysokosc[0]; i++)
	{
		(*(tmp + i)) = (struct Kolory*)malloc(1 + odczytywanie.wysokosc[0] * sizeof(struct Kolory));
		if (tmp[i] == NULL)
		{
			printf("Nie przydziela wartosci");
		}
	}
	*colors = tmp;

}

void AlokacjaPamieciszer(struct Kolory ***colors, struct Odczytuje odczytywanie){
	int i;
	struct Kolory **tmp;
	tmp = (struct Kolory**)malloc(1 + odczytywanie.wysokosc[0] * sizeof(struct Kolory*));
	for (i = 0; i< odczytywanie.wysokosc[0]; i++)
	{
		(*(tmp + i)) = (struct Kolory*)malloc(1 + 3 * odczytywanie.szerokosc[0] * sizeof(struct Kolory));
		if (tmp[i] == NULL)
		{
			printf("Nie przydziela wartosci");
		}
	}
	*colors = tmp;
}


void Przechowywanie(struct Odczytuje *odczyt, FILE *fP){
	fseek(fP, 0, 0);
	int i;
	fread((*odczyt).Bitmapa, 1, 2, fP);
	for (i = 0; i < 2; i++)
	{
		printf("%c", (*odczyt).Bitmapa[i]);
	}
	fread((*odczyt).rozmiar, 4, 1, fP);
	for (i = 0; i < 1; i++)
	{
		printf("\nRozmiar [w bajtach]: %d", (*odczyt).rozmiar[i]);
	}
	fread((*odczyt).reserved1, 4, 1, fP);
	fread((*odczyt).reserved2, 4, 1, fP);
	fread((*odczyt).reserved3, 4, 1, fP);
	fread((*odczyt).szerokosc, sizeof(int), 1, fP);
	for (i = 0; i < 1; i++)
	{
		printf("\nSzerokosc:%d", (*odczyt).szerokosc[i]);
	}
	fread((*odczyt).wysokosc, sizeof(int), 1, fP);
	for (i = 0; i < 1; i++)
	{
		printf("\nWysokosc: %d", (*odczyt).wysokosc[i]);
	}
	fread((*odczyt).planes, 2, 1, fP);
	printf("\nOffset: %d\n", (*odczyt).planes[0]);
}



void OdczytywanieKolorow(struct Kolory ***colors, struct Odczytuje odczytywanie, FILE *f1){
	int i = 0, j = 0;
	struct Kolory **temporary = NULL;
	AlokacjaPamieciwys(&temporary, odczytywanie);
	fseek(f1, 54, 0);
	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			fread(&temporary[i][j].blue, sizeof(unsigned char), 1, f1);
			fread(&temporary[i][j].green, sizeof(unsigned char), 1, f1);
			fread(&temporary[i][j].red, sizeof(unsigned char), 1, f1);
		}
	}
	*colors = temporary;
	

	/*
	for(i=0;i<macierz->w;i++) free(macierz->m[i]);
	free(macierz->m);
	free(macierz);
	*/

}

void Informacje(struct Odczytuje odczytywanie){
	int opcja, i = 0;
tu:
	printf("\n1. Typ pliku\n2. Rozmiar w bajtach \n3.Szerokosc i wysokosc \n4.Offset");
	scanf("%d", &opcja);
	if (opcja == 1)
	{
		for (i = 0; i < 2; i++)
		{
			printf("%c", odczytywanie.Bitmapa[i]);
		}
		goto tu;
	}
	if (opcja == 2){
		i = 0;
		printf("Rozmiar w bajtach: %d", odczytywanie.rozmiar[i]);
		goto tu;
	}
	if (opcja == 3)
	{
		printf("\nSzerokosc: %d\nWysokosc: %d", odczytywanie.szerokosc[i], odczytywanie.wysokosc[i]);
		goto tu;
	}
	if (opcja == 4)
	{
		printf("\nOffset: %d", odczytywanie.planes[i]);
		goto tu;
	}
}


//tutaj można dodać porównywarkę pikseli o tym samym kolorze (pętla for jeszcze raz)
void JasnyCiemny(struct Kolory **colors, struct Odczytuje odczytywanie){
	int i, j, nrjasnywys, nrjasnyszer, nrciemnywys, nrciemnyszer, suma, jasny = 0, ciemny = 800;

	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			suma = (int)(colors[i][j].blue) + (int)(colors[i][j].green) + (int)(colors[i][j].red);
			if (suma>jasny)
			{
				jasny = suma;
				nrjasnywys = i;
				nrjasnyszer = j;
			}
		}
	}
	printf("Najjasniejszy punkt o jasnosci lacznej: %d, element: %d %d", jasny, nrjasnywys, nrjasnyszer);

	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			suma = (int)(colors[i][j].blue) + (int)(colors[i][j].green) + (int)(colors[i][j].red);
			if (suma<ciemny)
			{
				ciemny = suma;
				nrciemnywys = i;
				nrciemnyszer = j;
			}
		}
	}
	printf("\nNajciemniejszy punkt o jasnosci lacznej: %d, element: %d %d", ciemny, nrciemnywys, nrciemnyszer);
}


void DoPliku(struct Kolory **colors, struct Odczytuje odczytywanie, FILE *picture, FILE*f1){

}

void ZamianaKanalow(struct Odczytuje odczytywanie, struct Kolory **colors, FILE*f1){
	int i, j, opcja;
	char variable;
	printf("\nZamien kanal: \n1. niebieski i czerwony \n2.niebieski i zielony \n 3. zielony i czerwony\n");
	scanf("%d", &opcja);
	if (opcja == 1)
	{
		fseek(f1, 54, 0);
		for (i = 0; i < odczytywanie.wysokosc[0]; i++)
		{
			for (j = 0; j < odczytywanie.szerokosc[0]; j++)
			{
				variable = colors[i][j].blue;
				colors[i][j].blue = colors[i][j].red;
				colors[i][j].red = variable;
				fwrite(&colors[i][j].blue, 1, 1, f1);
				fputc(colors[i][j].green, f1);
				fputc(colors[i][j].red, f1);
				fputc(0, f1);
			}
		}
	}
	if (opcja == 2)
	{
		fseek(f1, 54, 0);
		for (i = 0; i < odczytywanie.wysokosc[0]; i++)
		{
			for (j = 0; j < odczytywanie.szerokosc[0]; j++)
			{
				variable = colors[i][j].blue;
				colors[i][j].blue = colors[i][j].green;
				colors[i][j].green = variable;
				fputc(colors[i][j].blue, f1);
				fputc(colors[i][j].green, f1);
				fputc(colors[i][j].red, f1);
				fputc(0, f1);
			}
		}
	}
	if (opcja == 3)
	{
		fseek(f1, 54, 0);
		for (i = 0; i < odczytywanie.wysokosc[0]; i++)
		{
			for (j = 0; j < odczytywanie.szerokosc[0]; j++)
			{
				variable = colors[i][j].green;
				colors[i][j].green = colors[i][j].red;
				colors[i][j].red = variable;
				fputc(colors[i][j].blue, f1);
				fputc(colors[i][j].green, f1);
				fputc(colors[i][j].red, f1);
				fputc(0, f1);
			}
		}
	}
}

void SkalaSzarosci(struct Odczytuje odczytywanie, struct Kolory **colors, FILE*picture){


	int suma = 0, i = 0, j = 0;
	double szary1, szary2, szary3;
	char sz1, sz2 = 0, sz3 = 0, sum;
	fseek(picture, 54, 0);
	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			szary1 = 0.229*(double)(colors[i][j].blue);
			szary2 = 0.587*(double)(colors[i][j].green);
			szary3 = 0.114*(double)(colors[i][j].red);
			sz1 = (char)szary1;
			sz2 = (char)szary2;
			sz3 = (char)szary3;
			sum = sz1 + sz2 + sz3;
			fputc(sum, picture);
			fputc(sum, picture);
			fputc(sum, picture);
			fputc(0, picture);
		}
	}
}


void ProgowanieUstalone(struct Kolory **colors, struct Odczytuje odczytywanie, FILE*picture){
	int i, j, ustalona, suma, s1, s2, s3;
	printf("\nPodaj prog od 0 - 765:\n");
	scanf("%d", &ustalona);
	fseek(picture, 54, 0);
	for (i = 0; i < odczytywanie.wysokosc[0] - 1; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			s1 = (int)(colors[i][j].blue);
			s2 = (int)(colors[i][j].green);
			s3 = (int)(colors[i][j].red);
			suma = s1 + s2 + s3;
			if (ustalona>(int)suma)
			{
				fputc(0, picture);
				fputc(0, picture);
				fputc(0, picture);
				fputc(0, picture);
			}
			else
			{
				fputc(255, picture);
				fputc(255, picture);
				fputc(255, picture);
				fputc(0, picture);
			}
		}
	}
}

void ProgowanieAutomatyczne(struct Odczytuje odczytywanie, FILE*picture, struct Kolory **colors){
	int i, j, suma = 0, iCz = 0, iB = 0;
	double SredniaCzern, SredniaBiel, wartosc0 = 0, wartosc = 382.0, czern = 0, biel = 0;
	char srednia;
	for (;;)
	{
		for (i = 0; i < odczytywanie.wysokosc[0]; i++)
		{
			for (j = 0; j < odczytywanie.szerokosc[0]; j++)
			{
				suma = (int)(colors[i][j].blue) + (int)(colors[i][j].green) + (int)(colors[i][j].red);
				if (suma<wartosc)
				{
					czern += suma;
					iCz++;
				}
				else
				{
					biel += suma;
					iB++;
				}
			}
		}
		SredniaCzern = (czern / (double)(iCz));
		SredniaBiel = (biel / (double)(iB));
		wartosc = (SredniaCzern + SredniaBiel) / 2;
		if (fabs(wartosc0 - wartosc)<0.0001)
		{
			break;
		}
		wartosc0 = wartosc;
	}

	fseek(picture, 54, 0);
	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			suma = (int)(colors[i][j].blue) + (int)(colors[i][j].green) + (int)(colors[i][j].red);
			if ((double)(suma)<wartosc)
			{
				fputc(0, picture);
				fputc(0, picture);
				fputc(0, picture);
				fputc(0, picture);
			}
			else
			{
				fputc(255, picture);
				fputc(255, picture);
				fputc(255, picture);
				fputc(0, picture);
			}
		}
	}
}
void Odbicie(struct Odczytuje odczytywanie, FILE*picture, struct Kolory **colors){
	int i, j, opc;
	printf("Wpisz '1' jesli w poziomie, '2' jesli w pionie");
	scanf("%d", &opc);
	if (opc == 1){
		fseek(picture, 54, 0);
		for (i = 0; i < odczytywanie.wysokosc[0]; i++)
		{
			for (j = odczytywanie.szerokosc[0] - 1; j >= 0; j--)
			{

				fputc(colors[i][j].blue, picture);
				fputc(colors[i][j].green, picture);
				fputc(colors[i][j].red, picture);
				fputc(0, picture);
			}
		}
	}

	if (opc == 2){
		fseek(picture, 54, 0);
		for (i = odczytywanie.wysokosc[0] - 1; i >= 0; i--)
		{
			for (j = 0; j < odczytywanie.szerokosc[0]; j++)
			{

				fputc(colors[i][j].blue, picture);
				fputc(colors[i][j].green, picture);
				fputc(colors[i][j].red, picture);
				fputc(0, picture);
			}
		}
	}



}



void ObrotObrazu(struct Odczytuje odczytywanie, FILE*picture, struct Kolory **colors, struct Kolory **obrot){
	int opcja, j, i;
	char niebieski, zielony, czerwony;
	printf("\nObrot o: \n1. 90* \n2. 180*\n 3.270*");
	scanf("%d", &opcja);
	if (opcja == 1)
	{
		i = odczytywanie.szerokosc[0];
		odczytywanie.szerokosc[0] = odczytywanie.wysokosc[0];
		odczytywanie.wysokosc[0] = i;
		fseek(picture, 4, 14);
		fputc(odczytywanie.wysokosc[0], picture);
		fputc(odczytywanie.szerokosc[0], picture);
		fseek(picture, 54, 0);
		for (i = odczytywanie.wysokosc[0] - 1; i >= 0; i--)
		{
			for (j = 0; j < odczytywanie.szerokosc[0]; j++)
			{
				niebieski = colors[i][j].blue;
				zielony = colors[i][j].green;
				czerwony = colors[i][j].red;
				fputc(niebieski, picture);
				fputc(zielony, picture);
				fputc(czerwony, picture);
			}
		}
		i = odczytywanie.szerokosc[0];
		odczytywanie.szerokosc[0] = odczytywanie.wysokosc[0];
		odczytywanie.wysokosc[0] = i;

	}
	if (opcja == 2)
	{
		for (i = odczytywanie.szerokosc[0] - 1; i >= 0; i--)
		{
			for (j = odczytywanie.wysokosc[0] - 1; j <= 0; j--)
			{
				niebieski = colors[i][j].blue;
				zielony = colors[i][j].green;
				czerwony = colors[i][j].red;
				fputc(niebieski, picture);
				fputc(zielony, picture);
				fputc(czerwony, picture);
			}
		}
	}
	if (opcja == 3)
	{
		for (i = 0; i > odczytywanie.szerokosc[0]; i++)
		{
			for (j = odczytywanie.wysokosc[0] - 1; j <= 0; j--)
			{
				niebieski = colors[i][j].blue;
				zielony = colors[i][j].green;
				czerwony = colors[i][j].red;
				fputc(niebieski, picture);
				fputc(zielony, picture);
				fputc(czerwony, picture);
			}

		}
	}
}


void RozjasnianiePrzyciemnianie(struct Odczytuje odczytywanie, FILE*picture, struct Kolory **colors){
	int i, j;
	char niebieski, zielony, czerwony, wspolczynnik;
	printf("Aby przyciemnic obraz wybierz liczbe z zakresu od -255 do -1. Aby rozjasnic wybierz od 1-255");
	scanf("%lf", &wspolczynnik);
	fseek(picture, 54, 0);
	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			niebieski = wspolczynnik + colors[i][j].blue;
			zielony = wspolczynnik + colors[i][j].green;
			czerwony = wspolczynnik + colors[i][j].red;
			if (niebieski>255)
			{
				niebieski = 255;
			}
			if (zielony>255)
			{
				zielony = 255;
			}
			if (czerwony>255)
			{
				czerwony = 255;
			}
			fputc(niebieski, picture);
			fputc(zielony, picture);
			fputc(czerwony, picture);
			fputc(0, picture);


		}
	}
}


void Negatyw(struct Odczytuje odczytywanie, FILE*picture, struct Kolory **colors){
	char niebieski, zielony, czerwony;
	int i, j;

	for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		for (j = 0; j < odczytywanie.szerokosc[0]; j++)
		{
			niebieski = 255 - colors[i][j].blue;
			zielony = 255 - colors[i][j].green;
			czerwony = 255 - colors[i][j].red;
			fputc(niebieski, picture);
			fputc(zielony, picture);
			fputc(czerwony, picture);
			fputc(0, picture);

		}
	}
}


int main(){
	int zad, i = 0, j, kontynuacja=1;
	struct Odczytuje odczytywanie;
	struct Kolory **colors = NULL;
	struct Kolory **obrot = NULL;
	FILE *f1 = NULL;
	FILE *picture = NULL;
	picture = fopen("C:\\Users\\ACERR\\Desktop\\Łukasz\\Semestr III\\Informatyka II (P)\\asa\\asa\\informatykaKopia.bmp", "ab");
	f1 = fopen("C:\\Users\\ACERR\\Desktop\\Łukasz\\Semestr III\\Informatyka II (P)\\asa\\asa\\informatyka.bmp", "rb");

	if (!picture){
		printf("Blad");
	}
	if (!f1){
		printf("Blad");
	}
	Przechowywanie(&odczytywanie, f1);

	if (odczytywanie.szerokosc[0] % 4 != 0){			//padding
		odczytywanie.szerokosc[0] = odczytywanie.szerokosc[0] + 4 - (odczytywanie.szerokosc[0] % 4);
	}


	//AlokacjaPamieciwys(&colors, odczytywanie);
	while (kontynuacja == 1){
	printf("Podaj numer zadania:");
	scanf("%d", &zad);
	
		switch (zad){

		case 1:
			Przechowywanie(&odczytywanie, f1);
			break;
		case 2:	OdczytywanieKolorow(&colors, odczytywanie, f1);
			for (i = 0; i < odczytywanie.wysokosc[0]; i++)
			{
				printf(" %d ", colors[i][111].blue);
			}
			break;
		case 3:
			Informacje(odczytywanie);
			break;
		case 4:
			JasnyCiemny(colors, odczytywanie);
			break;

		case 5:
			fseek(f1, 0, SEEK_SET);
			char bufor;
			for (;;){

				bufor = fgetc(f1);
				if (!feof(f1)){
					fputc(bufor, picture);
				}
				else break;
			}
			printf("DONE!");


			DoPliku(colors, odczytywanie, picture, f1);
			break;
		case 6:
			ZamianaKanalow(odczytywanie, colors, f1);
			break;
		case 7:
			SkalaSzarosci(odczytywanie, colors, picture);
			break;
		case 8:
			ProgowanieUstalone(colors, odczytywanie, picture);
			break;
		case 9:
			ProgowanieAutomatyczne(odczytywanie, picture, colors);
			break;
		case 10:
			Odbicie(odczytywanie, picture, colors);
			break;
		case 11:
			ObrotObrazu(odczytywanie, picture, colors, obrot);
			break;
		case 12:
			RozjasnianiePrzyciemnianie(odczytywanie, picture, colors);
			break;
		case 13:
			Negatyw(odczytywanie, picture, colors);
			break;
		}
		printf("\n\nJesli chcesz kontynuowac wpisz 1:\n");
		scanf("%d", &kontynuacja);
	}
	for (i = 0; i < odczytywanie.wysokosc[i]; i++)
	{
		free(colors[i]);
	}

	free(colors);
	fclose(f1);
	fclose(picture);
	system("pause");
	return 0;
}

0

Wywal goto i początek, bo to jest jakaś masakra. Używaj pętli, switch.
W tej chwili masz wycieki pamięci za każdym razem jak wchodzisz do OdczytywanieKolorow(), bo alokujesz nową pamięć, a nie zwalniasz starej.

Jaki jest sens używania tablicy jednoelementowej?

int rozmiar[1];
int szerokosc[1];
int wysokosc[1];
0

Okej, rozumiem, że trzeba było usunąć alokację pamięci dla "colors" w funkcji main. Ale i tak mi wyrzuca błąd przy zwalnianiu pamięci. Te tablice może nie najlepsze rozwiązanie, ale na samych zmiennych nie działał fread, a na tablicach chciał sczytywać, więc tak zostawiłem

0

Jeśli wielokrotnie wybierasz opcję 2 to nadal będziesz miał wyciek. Za to jeśli ani razu nie wybrałeś 2 to teraz się wywali.
W innych przypadkach musisz sam debuggować. Skoro masz debugger śledź jaka jest wartość zmiennej colors (jest to jakiś adres). Od momentu alokacji do momentu dealokacji nie może się zmienić.

0
twonek napisał(a):

Jeśli wielokrotnie wybierasz opcję 2 to nadal będziesz miał wyciek. Za to jeśli ani razu nie wybrałeś 2 to teraz się wywali.
W innych przypadkach musisz sam debuggować. Skoro masz debugger śledź jaka jest wartość zmiennej colors (jest to jakiś adres). Od momentu alokacji do momentu dealokacji nie może się zmienić.

Zmienia się przy wyjściu z funkcji, ale podejrzewam, że tak ma być, bo w main'ie pracuje na innym obszarze pamięci niż w funkcji. Przy drugim razie (wybieram opcję 2 drugi raz) wywala program... Szczerze mówiąc to nie mam pojęcia jak temu zaradzić

EDIT: Przy daniu wartości z "tmp" w funkcji "alokacjapamieciwys" nie zmienia adresu komórki (jeśli o to chodzi).

0

Na początku w main zmienna colors ma wartość null, czyli 0. Gdy pierwszy raz zaalokujesz pamięć (prawdopodobnie w OdczytywanieKolorow()) wartość tej zmiennej się zmieni na jakąś liczbę. Od tego momentu do chwili wywołania free() ta wartość nie może się zmienić. Tak samo z wartością colors[0] (też nie może się zmienić). Jeśli się zmienia to znajdź moment, kiedy to nastąpiło i tam masz przyczynę swojego problemu.

0
twonek napisał(a):

Na początku w main zmienna colors ma wartość null, czyli 0. Gdy pierwszy raz zaalokujesz pamięć (prawdopodobnie w OdczytywanieKolorow()) wartość tej zmiennej się zmieni na jakąś liczbę. Od tego momentu do chwili wywołania free() ta wartość nie może się zmienić. Tak samo z wartością colors[0] (też nie może się zmienić). Jeśli się zmienia to znajdź moment, kiedy to nastąpiło i tam masz przyczynę swojego problemu.

Ta wartość się chyba nigdzie nie zmienia. Ewentualnie gdy chcę jeszcze raz ją wykonać... No, chyba że źle Cię rozumiem

0

Dobrze zrozumiałeś, ale resztę roboty (debuggowanie) musisz zrobić sam. Nikt za Ciebie tego nie zrobi. Możesz przenieść linijki z free() do różnych miejsc, żeby zobaczyć od którego momentu zaczyna być źle. Np. tuż po alokacji nie powinno być problemu. Potem kilka instrukcji dalej itd.

0

Z tym, że np. po samej alokacji wydaje się, że chodzi o tę zmienną "tmp", z której później kopiuje na wskaźnik "colors". Z tym, że to jest takie kopiowanie, które w cpp w działaniu na obiektach i klasach nazywa się płytkim kopiowaniem (nie wiem, czy w C też takie pojęcie istnieje) i jak zwalniam pamięć dla "tmp" to przy okazji zwalnia mi pamięć dla colors i ją gubię. :/ Nie wiem jak zrobić, żeby skopiowało tylko to co mnie interesuje (pamięć), a przy czyszczeniu pamięci dla "tmp" czyściło tylko dla tej tymczasowej zmiennej w funkcji, dla wskaźników zostawiając przydzieloną pamięć. Jakaś rada jak zrobić "głębokie kopiowanie" w C? Czy może złym tropem idę?

void AlokacjaPamieciwys(struct Kolory ***colors, struct Odczytuje odczytywanie){
    int i;
    struct Kolory **tmp = NULL;
    tmp = (struct Kolory**)malloc(odczytywanie.szerokosc[0] * sizeof(struct Kolory*));
    for (i = 0; i< odczytywanie.wysokosc[0]; i++)
    {
        (*(tmp + i)) = (struct Kolory*)malloc(1 + odczytywanie.wysokosc[0] * sizeof(struct Kolory));
        if (tmp[i] == NULL)
        {
            printf("Nie przydziela wartosci");
        }
    }
    *colors = tmp;

for (i = 0; i < odczytywanie.wysokosc[0]; i++)
	{
		free(tmp[i]);
	}

	free(tmp);
 
}
1

Nie nie nie. Masz nie zwalniać tmp, bo pod tym adresem jest pamięć którą zaalokowałeś i do której wskazuje potem colors.

*colors = tmp;

Tutaj nie kopiujesz żadnej pamięci. Jedyne co robisz to mówisz "od teraz *colors ma wskazywać na ten sam obszar pamięci co tmp, czyli na tę nowo zaalokowaną pamięć".

Mówiąc o przeniesieniu free() do różnych miejsc, miałem na myśli:

int main()
{
    ....
    OdczytywanieKolorow()
    free...
    ....
}

Odpalasz program wybierając tylko opcję 2 i patrzysz czy się wywala. Jeśli nie to lecisz dalej:

int main()
{
    ....
    ZamianaKanalow()
    free...
    ....
}

Odpalasz wybierając opcje 2 i 6. Jeśli się wywala to wiesz, że problem leży w ZamianaKanalow(). Jeśli nie to lecisz dalej itd.

0

Ok, to już wszystko rozumiem, tylko problem jest z tym, że mi wywala program dokładnie na czyszczeniu pamięci, czyli tam gdzie problemu właśnie być nie powinno. Przecież tylko chcę zwolnić pamięć, która na pewno jest prawidłowo nadana, bo ją wykorzystuję. Bo oprócz na debuggerze sprawdzam printf'em, czy wszystko się zgadza i wydaje się ok.

case 2:
			OdczytywanieKolorow(&colors, odczytywanie, f1);
for (i = 0; i < odczytywanie.wysokosc[0]; i++)
			{
				free(colors[i]);  //<--- w tym miejscu przy pierwszym przejściu (i=0)
			}
			free(colors);

EDIT: To samo się dzieje jak umieszcze

free()

w funkcji OdczytywanieKolorow i wyczyszcze "temporary" - BŁĄD. Jedynie jak umieszczę free()

 w funkcji AlokacjaPamieci() to przechodzi normalnie. Oczywiście żadna z tych opcji nie ma sensu w tym programie, ale nie rozumiem, czemu chce czyścić tylko w jednym miejscu, jednej funkcji, a w innych nie.
0

Jaki adres ma tmp[0] tuż po alokacji, a jaki adres colors[0] tuż przed dealokacją?

0

Dokładnie taki sam:

0x0109b070

0

Może odświeżę, bo nadal się z tym męczę. Co jeśli zmienia mi się adres komórki? Teraz tak mam

1

Gdy pierwszy raz zaalokujesz pamięć (prawdopodobnie w OdczytywanieKolorow()) wartość tej zmiennej się zmieni na jakąś liczbę. Od tego momentu do chwili wywołania free() ta wartość nie może się zmienić. Tak samo z wartością colors[0] (też nie może się zmienić). Jeśli się zmienia to znajdź moment, kiedy to nastąpiło i tam masz przyczynę swojego problemu.

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