Dynamiczna tablica obiektów- problem(wyswietla śmieci)

0

kod:

//dynamiczna tablica na obiekty
void create(test *wskaznik,int ile)
	{
	wskaznik=(test *)malloc(ile*sizeof(test));
	int i=0;
	for(i=0;i<ile;i++)
		{
		cout<<i<<" liczba \n";
		wskaznik[i].liczba=i;//bo obiekt
		}
	}

void get(test * wskazn,int liczba)//wyswietlanie
	{
	for(int i=0;i<liczba;i++)
		{
		cout<<wskazn[i].liczba;
		}
	}
void destroy(test *wk,int ile)//zupelnie niepotrzebny 2 argument ale mialo byc przeciązenie wiec jest
	{
	free(wk);
	}


użycie:

test *wsk2=(test*)malloc(sizeof(test));//dalem ponieważ bez tego wywalalo blad że niezainicjowana zmienna
create(wsk2,5);
get(wsk2,5);
destroy(wsk2,1);

niestety zamiast liczb 0,1,2,3,4 wyswietla śmieci z pamieci. Mi sie wydaje że wszystko w porzadku, kompilatorowi też.
Widzicie może co robie źle?

1

Wydaje mi się że problem jest wsk2. Robisz malloca, potem wywołujesz create który znowu (!) robi malloca i dopiero teraz czyni jakieś czary na tej pamięci. I teraz zagadka get dostaje wsk2 do której pamięci? Tej pierwszej czy tej zalokowanej w create? :)

1

Przede wszystkim wskaźnik możesz po prostu zainicjalizować wartością NULL. Po drugie to, że przekazujesz wskaźnik nie oznacza, że możesz zmieniać adres na jaki wskazuje. A to właśnie próbujesz zrobić wewnątrz funkcji create - przypisujesz adres zwrócony przez malloc. Ale nie zmieni to adresu, na jaki wskazuje wsk2 (zmieni się wskaznik wewnątrz funkcji) a wskazuje on na jakieś śmieci.

Jeżeli chcesz alokować wewnątrz funkcji - zwróć ten wskaźnik.

Ładnie to widać, jeżeli użyjesz sobie typedef:

typedef int * int_ptr_t;

Jeżeli teraz napiszesz taką funkcję:

void funkcja(int_ptr_t wskaznik) {
  wskaznik = jakas_tam_wartosc;
}

To sam przyznasz, że przecież nie zmieni to wartości tej zmiennej. Dokładnie to teraz robisz. Trzeba zastosować podejście ze wskaźnikami:

void funkcja(int_ptr_t *wskaznik) {
  *wskaznik = jakas_tam_wartosc;
}

A do funkcji przesłać adres:

funkcja(&jakis_wskaznik);

W rzeczywistości masz teraz podwójny wskaźnik, ale nie ma to dla Ciebie znaczenia, bo ten pierwszy jest ukryty przez typedef i piszesz "normalnie".

(Przykład: http://ideone.com/OJDmqh)

0
void create(test **wskaznik,int ile)
	{
	*wskaznik=(test *)malloc(ile*sizeof(test));
	int i=0;
	for(i=0;i<ile;i++)
		{
		*wskaznik[i].liczba=i;// tutaj sie wywala
		}
	} 

create((test **)&wsk2,5);

Faktycznie teraz zmienia adres, ale mam problem- podejrzewam że chodzi o coś z priorytetem operatorów ale jak wciskam jakieś nawiasy w "*wskaznik[i].liczba=i;" to debbuger mowi coś że bledne typowanie.

Piwo Ci wisze, jakbyś był kiedyś w Szczecinie to daj znać: )

1

Jest jeszcze jeden sposób:

struct TabelaTest
  {
   Test *wskaznik;
   unsigned Ile;
  };

void create(struct TabelaTest *tabela,unsigned Ile) ...
 void get(struct TabelaTest *tabela) ...
void destroy(struct TabelaTest *tabela) ...

w main robisz:

   TabelaTest T;
  create(&T,10);
  get(&T);
  destroy(&T);
1

Faktycznie teraz zmienia adres, ale mam problem- podejrzewam że chodzi o coś z priorytetem operatorów ale jak wciskam jakieś nawiasy w "*wskaznik[i].liczba=i;" to debbuger mowi coś że bledne typowanie.

Operator [] ma wyższy priorytet od *. Dlatego najpierw musisz zrobić dereferencję a dopiero potem możesz posługiwać się tym jak tablicą. Powinno być (*wskaznik)[i].liczba = i;

0

Można to rozwiązać w bardziej elegancki sposób aby nie robić dodatkowych operacji w pętli:

test *wsk=(test *)malloc(ile*sizeof(test));
*wskaznik=wsk;
...
wsk[i].liczba=i;

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