Skocz do zawartości

Dziwne zachowanie wskaźnika


Pomocna odpowiedź

Taki problem(wyjaśnienie pod źródłami):

.h

typedef enum{
	_ok = 0,
	_err
}_menu_stat_t;

typedef enum{
	_next = 0,
	_prev,
	_child,
	_parent,
	__naviEnd
}_menuNavi_t;

typedef struct menu{
const struct menu * menuNav[4];
const uint8_t id;//,node;
}menu_t;

.c

_menu_stat_t menu_navigator(menu_t ** p,uint8_t * id,int8_t * nodeDir,_menuNavi_t navi){

	if(navi >= __naviEnd){ // gdy polecenie nieznane
		return _err;
	}

	menu_t * mn = (menu_t*)*p;

	if(NULL != mn->menuNav[navi]){ // spr czy po nie pusta
		*p = (menu_t*)mn->menuNav[navi];
		*id = mn->id;
			if(navi == _parent)*nodeDir = -1; // nawigacja po wezlach
			if(navi == _child)*nodeDir = 1;

		return _ok;
	}
	return _err;
}

Funkcja ma za zadanie przekazać nową wartość wskaźnika jeśli jest różny od null, odnosi się ona do tablicy wskaźników:

const menu_t menuGl[] = {

		{ //zegar
		.menuNav[_next] = &menuGl[l1],
		.menuNav[_prev] = &menuGl[lend],
		.menuNav[_child] = &menuTime[0], // ust godz
		.menuNav[_parent] = NULL,
		.id = l0
		},

		{	//bright
		.menuNav[_next] = &menuGl[l2],
		.menuNav[_prev] = &menuGl[l0],
		.menuNav[_parent] = NULL,//&menuGl[_mOn],
		.menuNav[_child] = NULL,
		.id = l1
		},

		{	//lang
		.menuNav[_next] = &menuGl[lend],
		.menuNav[_prev] = &menuGl[l1],
		.menuNav[_parent] = NULL,
		.menuNav[_child] = NULL,
		.id = l2
		},

		{	//end
		.menuNav[_next] = &menuGl[l0],
		.menuNav[_prev] = &menuGl[l2],
		.menuNav[_parent] = NULL,
		.menuNav[_child] = &menuOn[0], // wyjscie
		.id = lend
		},
};

Dane w tej tablicy są poukładane poprawnie, problem tkwi w tym że kiedy zmieniam kierunek pobierania elementów tablicy wpierw pointer wskazuje na ten(kierunek) który był użyty wcześniej a potem ten prawidłowy. Tj: jadę z elementami po kolei od l0 do end do l0 to działa elegancko indeksy są pobierane prawidłowo, kiedy jednak jestem na dowolnym indeksie ale zmienię kierunek pobierania to wpierw wykonuje się ostatnia instrukcja a potem dopiero iteracja następuje tak jak ma być. Miałem wersję funkcji menu_navigator kiedy w returnie nie był przekazywany status, a wskaźnik i wtedy działało prawidłowo, stąd mój domysł że coś jest nie tak w menu_navigator. Nie umiem sobie z tym poradzić a tutaj funkcja która wywołuje navigatora

void runCmd(cmd_t cmd) {
	menuVisible = 1;	//info dla prog glownego ze menu powinno byc wyswietlone
	static menu_t * ptrMenu = (menu_t*)menuOn;
	uint8_t id = 0;
	int8_t node = 0;
	_menu_stat_t stat = menu_navigator(&ptrMenu, &id, &node,cmd);
	if(node!=0)id=0; // zerowanie ideksu nowy pointer
	if (_ok == stat)menu_execute(id,node,menu.outStream);
}

 

 

 

 

Edytowano przez _LM_
Link to post
Share on other sites

@_LM_Takie fajne analizowanie funkcji do której hgw co się wrzuca.

Ja na razie widzę jedno:

if(navi == _parent)*nodeDir = -1; // nawigacja po wezlach
if(navi == _child)*nodeDir = 1;
// a co jak navi jest np. _next?

		

Ale nie wiem jak wywołujesz tę funkcję...

Link to post
Share on other sites
(edytowany)

Ten kawałek niema znaczenia w problemie który opisuję, można by to usunąć i nadal będzie działało źle. Ale skoro pytasz, należy wyjaśnić: ten kawałek później zmienia adresy struktur menu na kolejne, gdyż ta którą pokazałem jest jedną z wielu. Kiedy navi jest _next albo _prev dzieje się to

		*p = (menu_t*)mn->menuNav[navi];
		*id = mn->id;

Problem tkwi w tej nawigacji właśnie: jeśli przychodzi _next, _next.... działa dobrze i pokazuje kolejne wartości ALE gdy zmienię kierunek na _prev to w następnym kroku zachowa się jakby było _next a potem dopiero dzieje się _prev  

Edytowano przez _LM_
Link to post
Share on other sites

Wniosek jest taki że przekazany wskaźnik na wskaźnik **p nie zmienia swojej wartości za pierwszym podejściem

Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Z tego co zamieściłeś i co napisałeś o objawach można wywnioskować jedno: gdzieś jest błąd. Natomiast gdzie - najprawdopodobniej w tym kawałku kodu co go nie pokazałeś 😉

 

Link to post
Share on other sites

OK nie to żebym nie chciał całości pokazywać, bo tego jest od cholery i tym bardziej się nikt nie połapie. Powiedz mi dlaczego kiedy w returnie fukcji menu_navigator zwracałem nowy wskaźnik to działało a kiedy jest jak teraz to są problemy? Jestem 100% pewny że robię błąd właśnie w funkcji navigator 

Link to post
Share on other sites

Albo inaczej, zrobię próbkę na mniejszym kodzie i zamieszczę, w końcu to mi zależy 🙂

 

Link to post
Share on other sites
(edytowany)

Jak dla mnie ta funkcja wygląda zdrowo...

A zresztą dzisiaj już nie popatrzę, właśnie jestem świeżo po znalezieniu durnego babola w funkcji która podobno była bezbłędna (zapomniałem podać offset przy czytaniu z shm 🙂 )

Edytowano przez ethanak
  • Lubię! 1
Link to post
Share on other sites

Spoczko, podejrzewam że mój błąd też jest trywialny tak to wygląda:

Tak jak pisałem klikanie pozycji po kolei wyświetla dane wg oczekiwań, zmiana kierunku nawigacji powoduje problemy

Link to post
Share on other sites

Tak z ciekawości - a gdyby zmienić:

		*p = (menu_t*)mn->menuNav[navi];
		*id = mn->id;

na:

		*p = (menu_t*)mn->menuNav[navi];
		*id = (*p)->id;

?

  • Lubię! 1
  • Pomogłeś! 1
Link to post
Share on other sites
(edytowany)

DZIAŁA!!! Wow dzięki 🙂 a teraz jakbyś mógł wytłumaczyć dlaczego? I czy można się pozbyć tego wskaźnika mn?

Edytowano przez _LM_
Link to post
Share on other sites

@_LM_ Przecież to Twój program, powinieneś rozumieć jak działa... Zrozumienie gdzie jest błąd to chyba dobre ćwiczenie. Ale jeśli nic nie wymyślisz to podpowiem 🙂

  • Lubię! 1
Link to post
Share on other sites

A no tak, id pobierałem z tego na co wskazywał mn przed ifem więc starą pozycję 

  • Lubię! 1
Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.