[ansi C] tablice dynamiczne


(Kubal92) #1

Witam.

Potrzebuję pomocy z zapełnianiem tablicy dynamicznej w C. Siedzę nad tym już wiele godzin, a w google nie mogę znaleźć zrozumiałych dla mnie odpowiedzi, które by mi to wytłumaczyły, a czas płynie bardzo szybko.

Mam dwie struktury - oprawa i szklo. Mają one po dwa elementy (dobrze to nazwałem?) -int cena oraz int numer. Muszę dynamicznie stworzyć ich tablice, a następnie te tablice wypełnić, gdzie int numery są wypełniane automatycznie od 0 do n (aktualnie w kodzie jest do 5), a int ceny są ustawiane przez użytkownika. Na koniec, po wywołaniu w switchu funkcji "czyszczących", te tablice muszą być usunięte.

Podany kod da się skompilować, ale program od razu się crashuje, bo źle próbuję stworzyć tablice. Wiem też, że w C nie ma czegoś takiego jak referencja (te funkcje dodające elementy w switchu są źle napisane), więc powinienem przez returna zwrócić wartości tablic, ale nie wiem jak dokładnie to zrobić.

#include 

#include 


typedef struct oprawa

{

	int numer;

	int cena;

}oprawa;


typedef struct szklo

{

	int numer;

	int cena;

}szklo;


oprawa stworz_tablice_opraw(oprawa * tablica_opraw)

{

	tablica_opraw = (oprawa*)malloc(5*sizeof(oprawa));

	return *tablica_opraw;

}


szklo stworz_tablice_szkiel(szklo * tablica_szkiel)

{

	tablica_szkiel = (szklo*)malloc(5*sizeof(szklo));

	return *tablica_szkiel;

}


int menu(int wybor)

{

	printf("\n1)Dodaj oprawe,\n2)Dodaj szklo,\n3)Wyczysc pamiec, \n4)Wyswietl dane,"

			"\n9)Wyjdz z programu.\n\n\nPodaj numer opcji do wyboru: ");

	scanf("%d",&wybor);


	return wybor;

}


int koniec_pracy(int wybor)

{

	printf("\n\nKoniec pracy programu.\n");

	return 9;

}


int error(int wybor)

{

	printf("\n\nPodales niewlasciwa komende.\n");

	return 0;

}


int dodaj_oprawe(oprawa * tablica_opraw)

{

	int cena;

	for(int i = 0; i < 5; i++)

	{

		printf("\nPodaj cene oprawy nr ",i," : ");

		scanf("%d",&cena);

		tablica_opraw[i].cena = cena;		

	}


	return ilosc;

}


int dodaj_szklo(szklo * tablica_szkiel)

{

	int cena;

	for(int i = 0; i < 5; i++)

	{

		printf("\nPodaj cene szkla nr ",i," : ");

		scanf("%d",&cena);

		tablica_szkiel[i].cena = cena;		

	}


	return ilosc;

}


void wyswietl(oprawa * tablica_opraw, szklo * tablica_szkiel)

{

	for (int i = 0; i < 5; i++)

	{

		printf("Oprawa nr. ",i," kosztuje ",tablica_opraw[i].cena);

		printf("szklo nr. ",i," kosztuje ",tablica_szkiel[i].cena);

	}

}


oprawa wyczysc_oprawy(oprawa * tablica_opraw)

{

	printf("\nOprawy usuniete.");

	free(tablica_opraw);


	return *tablica_opraw;

}


szklo wyczysc_szkla(szklo * tablica_szkiel)

{

	printf("\nSzkla usuniete.");

	free(tablica_szkiel);


	return *tablica_szkiel;

}


// /=============\ //

//============================== funkcja main =============================//

// \=============/ //


int main() 

{

	int ilosc;


	oprawa * tablica_opraw;

	szklo * tablica_szkiel;


	*tablica_opraw = stworz_tablice_opraw(tablica_opraw);

	*tablica_szkiel = stworz_tablice_szkiel(tablica_szkiel);



	int wybor = 0;	

	while(wybor != 9)

	{

		wybor = menu(wybor);		

		switch(wybor)

		{

			case 1:

				dodaj_oprawe(tablica_opraw);

				break;

			case 2:

				dodaj_szklo(tablica_szkiel);

				break;

			case 3:

				wyczysc_oprawy(tablica_opraw);

				wyczysc_szkla(tablica_szkiel);

				break;

			case 4:

				wyswietl(tablica_opraw, tablica_szkiel);

				break;

			case 9:

				wybor = koniec_pracy(wybor);

				break;

			default:

				wybor = error(wybor);

				break;

		}

	}

	system("pause");	

	return 0;

}


// /====================\ //

//========================== koniec funkcji main =========================//

// \====================/ //

(Alpine7) #2

Zdecyduj sie czy chcesz przekazac wskaznik jako argument czy go zwracac. Zrob funkcje zwracajace wskaznik, w ktorych przydzielisz pamiec i zwroc potem te wskazniki. Zamiast wskaznika jako argument daj sobie ilosc tych elementow tablicy.

#include 

#include 


typedef struct oprawa

{

   int numer;

   int cena;

}oprawa;


typedef struct szklo

{

   int numer;

   int cena;

}szklo;


oprawa* stworz_tablice_opraw(int ilosc)

{

   oprawa* tablica_opraw = (oprawa*)malloc(ilosc*sizeof(oprawa));

   return tablica_opraw;

}


szklo* stworz_tablice_szkiel(int ilosc)

{

   szklo* tablica_szkiel = (szklo*)malloc(ilosc*sizeof(szklo));

   return tablica_szkiel;

}


int main() 

{  

   oprawa * tablica_opraw = stworz_tablice_opraw(5);

   szklo * tablica_szkiel = stworz_tablice_szkiel(5);


   return 0;

}

(Kubal92) #3

Dzięki za odpowiedź, już rozumiem dodawanie elementów do tablicy za pomocą funkcji. Mam jednak kolejny problem - nie mogę zwolnić tych tablic dynamicznych.

Kiedy próbuję zniszczyć te tablice za pomocą funkcji:

oprawa * wyczysc_oprawy(oprawa * tablica_opraw)

{

	printf("\nOprawy usuniete.");

	free(tablica_opraw);


	printf("\n");			

	return tablica_opraw;

}


szklo * wyczysc_szkla(szklo * tablica_szkiel)

{

	printf("\nSzkla usuniete.");

	free(tablica_szkiel);


	printf("\n");			

	return tablica_szkiel;

}

To wciąż mogę odczytać wartości tablic - nie są one niszczone, tylko kilka pierwszych wartości przyjmuje zera. Jak mogę bezpowrotnie zniszczyć te tablice? Tutaj jest kod całego programiku:

#include 

#include 


typedef struct oprawa

{

	int numer;

	int cena;

}oprawa;


typedef struct szklo

{

	int numer;

	int cena;

}szklo;


oprawa* stworz_tablice_opraw(int ilosc)

{

   oprawa* tablica_opraw = (oprawa*)malloc(ilosc*sizeof(oprawa));

   return tablica_opraw;

}


szklo* stworz_tablice_szkiel(int ilosc)

{

   szklo* tablica_szkiel = (szklo*)malloc(ilosc*sizeof(szklo));

   return tablica_szkiel;

}


int menu(int wybor)

{

	printf("\n1)Dodaj oprawe,\n2)Dodaj szklo,\n3)Wyczysc pamiec, \n4)Wyswietl dane,"

			"\n9)Wyjdz z programu.\n\n\nPodaj numer opcji do wyboru: ");

	scanf("%d",&wybor);


	return wybor;

}


int koniec_pracy(int wybor)

{

	printf("\n\nKoniec pracy programu.\n");

	return 9;

}


int error(int wybor)

{

	printf("\n\nPodales niewlasciwa komende.\n");

	return 0;

}


oprawa * dodaj_oprawe(oprawa * tablica_opraw, int ilosc)

{

	int cena;

	for(int i = 0; i < ilosc; i++)

	{

		printf("\nPodaj cene oprawy nr ",i," : ");

		scanf("%d",&cena);

		tablica_opraw[i].cena = cena;		

	}


	return tablica_opraw;

}


szklo * dodaj_szklo(szklo * tablica_szkiel, int ilosc)

{

	int cena;

	for(int i = 0; i < ilosc; i++)

	{

		printf("\nPodaj cene szkla nr ",i," : ");

		scanf("%d",&cena);

		tablica_szkiel[i].cena = cena;		

	}


	return tablica_szkiel;

}


void wyswietl(int ilosc, oprawa * tablica_opraw, szklo * tablica_szkiel)

{

	for (int i = 0; i < ilosc; i++)

	{

		printf("\nOprawa nr. %d",i);

		printf(" kosztuje %d",tablica_opraw[i].cena);

		printf("\nSzklo nr. %d",i);

		printf(" kosztuje %d",tablica_szkiel[i].cena);

	}

	printf("\n");

}


oprawa * wyczysc_oprawy(oprawa * tablica_opraw)

{

	printf("\nOprawy usuniete.");

	free(tablica_opraw);


	printf("\n");			

	return tablica_opraw;

}


szklo * wyczysc_szkla(szklo * tablica_szkiel)

{

	printf("\nSzkla usuniete.");

	free(tablica_szkiel);


	printf("\n");			

	return tablica_szkiel;

}


int ile(int x)

{

	zawroc:

	printf("\nPodaj wielkosc tablic do wykonania (liczba dodatnia, rozna od zera): ");

	scanf("%d",&x);

	if (x < 1)

		goto zawroc;

	return x;

}


// /=============\ //

//============================== funkcja main =============================//

// \=============/ //


int main() 

{

	int ilosc = ile(ilosc);

	oprawa * tablica_opraw = stworz_tablice_opraw(ilosc);

    szklo * tablica_szkiel = stworz_tablice_szkiel(ilosc);	


	int wybor = 0;	

	while(wybor != 9)

	{

		wybor = menu(wybor);		

		switch(wybor)

		{

			case 1:

				tablica_opraw = dodaj_oprawe(tablica_opraw, ilosc);

				break;

			case 2:

				tablica_szkiel = dodaj_szklo(tablica_szkiel, ilosc);

				break;

			case 3:

				tablica_opraw = wyczysc_oprawy(tablica_opraw);

				tablica_szkiel = wyczysc_szkla(tablica_szkiel);

				break;

			case 4:

				wyswietl(ilosc, tablica_opraw, tablica_szkiel);

				break;

			case 9:

				wybor = koniec_pracy(wybor);

				break;

			default:

				wybor = error(wybor);

				break;

		}

	}

	system("pause");	

	return 0;

}


// /====================\ //

//========================== koniec funkcji main =========================//

// \====================/ //