Skocz do zawartości

Dziwne zachowanie wskaźnika


Pomocna odpowiedź

Napisano (edytowany)

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_

@_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ę...

(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_

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

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ś 😉

 

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 

(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

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

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
(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_

@_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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...