[C] Dealokovanie viacrozmerneho pola

Programovacie jazyky, rady, poradňa...
Klingac104
Novice
Novice
Príspevky: 4
Registrovaný: 24 nov 2012, 23:17

[C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa Klingac104 »

Čaute. Mám napísanu nejakú takúto funkciu:

Kód: Vybrať všetko

char **loadName(FILE *f)
{
char **pole;

free(pole);

vytvorenie a zapisanie do dvojrozmerneho pola...

return pole;

}
V zadaní mám napísane: Ak už bolo pole predtým načítané, je najprv dealokované a potom sa vytvorí nové...
Teda vždy ked zavolám tuto funkciu tak by sa mi malo toto pole dealokovať a vytvoriť nové.

Chcem sa opýtať či to free(pole) je napísané dobre. Či to nemá byť free(*pole), alebo či neni nejaký iný spôsob dealokovania pola. Dik
pcsiete
Medium Star
Medium Star
Príspevky: 413
Registrovaný: 07 dec 2012, 18:47

Re: [C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa pcsiete »

čo som len tak narýchlo zbúchal:

Kód: Vybrať všetko

void loadName(FILE *f) {
	static char** pole = NULL;
	static char** dlzka = 0;
	int i;
	
	if(pole!=NULL) {
		for(i = 0;i < dlzka;i++)
			free(pole[i]);
			
		free(pole);
	}	
	
	dlzka = /* pocet elementov pola */
	pole = (char**)malloc(dlzka*sizeof(char*));
	for(i = 0;i < dlzka;i++)
		pole[i] = (char*)malloc(/* velkost druhej dimenzie */);
		
	...
}
Hensym
VIP
VIP
Používateľov profilový obrázok
Príspevky: 6978
Registrovaný: 24 apr 2011, 0:53
Bydlisko: Zvolen

Re: [C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa Hensym »

pcsiete: Tvoj spôsob mi spôsobuje spadnutie programu.

Mám to 2D pole vytvorené v maine, teda funkcia je volaná s argumentom (&pole), a hlavičku má:

Kód: Vybrať všetko

funkcia (***pole){}
Tvoj kód na dealokáciu som teda upravil na:

Kód: Vybrať všetko

if(*pole!=NULL) {
      for(i = 0;i < dlzka;i++)
         free(*pole[i]);
         
      free(*pole);
   }  
No program po spustení funkcie spadne bez chybovej hlášky. (ConsoleApp has stopped working)
pcsiete
Medium Star
Medium Star
Príspevky: 413
Registrovaný: 07 dec 2012, 18:47

Re: [C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa pcsiete »

Tvoje pole je char***.

Kód: Vybrať všetko

if(*pole!=NULL)
// toto je OK

free( *pole[i] );
// sa podľa prednosti operátorov sa rozkladá na:
free( *(pole[i]) );
// namiesto očakávaného:
free( (*pole)[i] );
// pretože precedencia [] je vyššia ako pre *
Mohlo by to vyzerať niejako takto:

Kód: Vybrať všetko

void vyberRiadky(FILE* f, char*** pole_ptr, int* dlzka) {
	int i;
	
	//ak pole, ktoré bolo cez pointer predané do funkcie existuje (!= NULL)
	if(*pole_ptr != NULL) {
		//pre každý prvok poľa ktoré je (*pole_ptr)
		for(i = 0;i < *dlzka;i++)
			free((*pole_ptr)[i]); //dealokuj
         
		//dealokuj aj pole samotné
		free(*pole);
	}   
	
	/* kód ktory pracuje zo suborom */
	
	//nastav premennú ktorá je (*dlzka) na počet riadkov
	*dlzka = ...;
	//alokuj pole pre riadky, ulož do (*pole_ptr)
	*pole_ptr = (char**)malloc(*dlzka * sizeof(char*));
	
	//a potom už pre každý riadok v poli (*pole_ptr)
	for(i = 0;i < *dlzka;i++)
		//alokuj miesto pre reťazec
		(*pole_ptr)[i] = (char*)malloc(/* veľkost riadka */);
	
	...
}
S použitím ako:

Kód: Vybrať všetko

FILE * subor = ....;
char** riadky = NULL;
int pocetRiadkov = 0;

vyberRiadky(subor, &riadky, &pocetRiadkov);
Hensym
VIP
VIP
Používateľov profilový obrázok
Príspevky: 6978
Registrovaný: 24 apr 2011, 0:53
Bydlisko: Zvolen

Re: [C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa Hensym »

Ďakujem, spravil som to takto, program to bere, ale dal som spraviť som kontrolný výpis:

Kód: Vybrať všetko

if(*pole != NULL) //dealokuj

if(*pole != NULL) printf("nie je prazdne");
Ten printf by sa teda nikdy nemal vykonať, pretože vždy sa najskôr pole dealokuje, no vypisuje sa vždy.
pcsiete
Medium Star
Medium Star
Príspevky: 413
Registrovaný: 07 dec 2012, 18:47

Re: [C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa pcsiete »

free nenastaví pointer na NULL, len dealokuje pamäť na ktorú ukazuje. Na NULL si ho už musíš nastaviť ty, čo v tejto funkcii nie je nevyhnutné.

Ale pravda, malo by to byť takto

Kód: Vybrať všetko

		...

		//dealokuj aj pole samotné
		free(*pole);
		*pole = NULL;
}
Hensym
VIP
VIP
Používateľov profilový obrázok
Príspevky: 6978
Registrovaný: 24 apr 2011, 0:53
Bydlisko: Zvolen

Re: [C] Dealokovanie viacrozmerneho pola

Príspevok od používateľa Hensym »

Jasné, to mi nedošlo. Vďaka za pomoc. :) :plus:
Napísať odpoveď