ATNEL tech-forum
https://forum.atnel.pl/

[C] Znikająca wartość tablicy
https://forum.atnel.pl/topic21729.html
Strona 1 z 1

Autor:  Palvanen [ 19 gru 2018, o 14:32 ]
Tytuł:  [C] Znikająca wartość tablicy

Witam.

Napotkałem na nietypowy problem. Otóż opracowuję sobie pewien programik pomagający przeliczać stany urządzenia sterowanego AVRem. Program na PC.
Posiadam zadeklarowaną i uzupełnioną zerami tablicę znaków:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Kolejno obliczają się dane, które mają być zapisane do tablicy_1 oraz alternatywne dane zapisywane do tablicy_2.
Kolejno mam funkcję, która brzmi mniej więcej tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


No i ok. Powstają mi dwa ładnie wygenerowane bufory główne i alternatywne.
Do tablicy tablica_1 wklejany jest bufor główny, do tablicy tablica_2 wklejany jest bufor alternatywny.

Kolejno w programie pobieram sobie kolejny wyraz z tablic i wykonują się dwie pętle na tablicy_1 i tablicy_2.
Niezależnie od tego w jakiej kolejności zapisuję tablice i odczytuję tablice, zawsze w drugiej pętli gubiony jest pierwszy wyraz tablicy.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Adresy sprawdzane przez "%p" przekazywanych zmiennych się zgadzają, rozmiary tablic się zgadzają, zapisywane dane są "debugowane" i wyświetlane przed zapisem do tablic.
Typy danych zgodne z typem tablic. Przewidziany zakres miejsca w przypadku char i /0. No i tyle mi przychodzi do głowy...

Czy jest szansa na jakąś sugestię tej zagadki?

Autor:  Palvanen [ 19 gru 2018, o 14:53 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Program na PC, więc int, uint, bez znaczenia. To jest taki program pomocniczy dla mnie. AVRa samego się nie czepiamy, bo tu jest ok.
Postaram się jeszcze ten opis skrócić, jak wygląda wypluwanie wyników w pętli.
Załóżmy, że przeszliśmy etap wypełnienia pętli. I dla uproszczenia wyniki:
1 wykonanie pętli for dla tablicy tablica_1:
i = 0 -> wartość = 1;
i = 1 -> wartość = 2;
i = 2 -> wartość = 3;
i = n -> wartość = k;
To samo i tak samo z tablicą wartości alternatywnych tablica_2.
Wyplute prawidłowo wartości z pętli są przeliczane.
I potrzebne ponowne wykonanie pętli. No to jedziemy:
tablica_1:
i = 0 -> wartość = 1;
i = 1 -> wartość = 2;
i = 2 -> wartość = 3;
i = n -> wartość = k;
No i jest wszystko ok.
Teraz druga tablica:
tablica_2 (wartości alterantywne):
i = 0 -> wartość = NULL; (tylko tutaj jest problem)
i = 1 -> wartość = 2; a dalej wypisuje prawidłowo do ostatniej wartości.
i = 2 -> wartość = 3;
i = n -> wartość = k;

No i zonk.

Autor:  Lex_ [ 19 gru 2018, o 16:39 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Ciekawa zagadka. Cały listing kodu byłby lepszy do analizy. Tak czy siak podejrzewałbym albo nie wpisanie wartości do tablicy lub nadpisanie tablicy nr 2 ponieważ C (może i C++) czasami optymalizuje dostęp do komórek pamięci umieszczając jedną tablicę zaraz za drugą. Wartość NULL świadczyłaby o tym że gdzieś tutaj jest problem bo inaczej byłaby jakaś wartość a tak nie jest.
Sprawdź czy tak jest - tzn wyświetl sobie adresy tablicy 1 i tablicy 2. Jeżeli tak jest to zmniejsz tablicę 1 i sprawdź efekt.

:edit - napisane na szybko:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  Palvanen [ 19 gru 2018, o 16:53 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Miałem już próbować wykonać podana wyżej propozycję, ale z ciekawości chciałem wykonać kompilację na innej platformie systemowej.
Ponieważ nie mam aktualnie dostępu do własnego komputera, do takich celów mam w swoim telefonie zainstalowany emulator z Arch Linux for amr i zainstalowanym gcc. Wykonałem kompilację i uwaga... Działa...
Do tej pory wykonywałem kompilacje na Windowsie.
Do kompilowania zaprzęgnięte mingw w Code Blocks.
Czyli co? Coś jest źle napisane i mam zmieniać logikę, czy kompilator w windowsie ma problem?
Podejrzewam, że gdyby coś z adresami było nie tak, to byłby ten sam efekt i w linuksie.
Postaram się mimo wszystko późnym wieczorem lub w dniu jutrzejszym przyjrzeć jakie tam adresy latają, bo na Windowsie też musi działać.

Autor:  Lex_ [ 19 gru 2018, o 16:55 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Mingw to GCC więc jest to dziwne. Ale jak będziesz miał możliwość to sprawdź bo ciekawy przypadek.

Autor:  Zealota [ 19 gru 2018, o 17:47 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Palvanen napisał(a):
Witam.

Napotkałem na nietypowy problem. Otóż opracowuję sobie pewien programik pomagający przeliczać stany urządzenia sterowanego AVRem. Program na PC.
Posiadam zadeklarowaną i uzupełnioną zerami tablicę znaków:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czemu uważasz, że masz dwie tablice wypełnione zerami?
Wg mnie masz tablice z pierwszym elementem równym 0, a reszta to losowe dane.
A może ta definicja tablicy to skrót myślowy?
No chyba, że te tablice są globalne albo static. To niestety nie wynika z kodu, który podałeś.
Jeśli są globalne lub static to oczywiście nie musisz ich wypełniać zerami, bo zrobi to za Ciebie kompilator.

Autor:  Palvanen [ 19 gru 2018, o 18:57 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Do przedmówcy:
Skrót myślowy. 0x0 to nawet nie 0, ponieważ żeby to było lepiej widoczne, powinno być 0x30 i wtedy by było "zero". Ale ok. Wprowadziłem w błąd tym zapisem. Jak to mówią, za dużo myśli na sekundę ;)
W każdym razie na 100% tablice są wypełnione zerami.
No i teraz poszedłem wg poprzedniego zalecenia i prześledziłem adresy, oraz co w nich siedzi. Okroiłem rozmiar obu tablic do 4 parametrów.
Wykonałem kompilację tego kodu na Windowsie i w linuksie, tym razem w wersji desktopowej linuksa.
Załączam dwa obrazki. Jak widać w wynikach linuksowych zawartości tablic się zgadzają.
Natomiast w wersji windowsowej teraz wydarzyło się jeszcze co innego. Nie tyle pierwsza wartość została skasowana, co zostały zmienione dwie środkowe wartości. Teraz tym bardziej nie mogę ogarnąć co to może powodować. Zaznaczam, że druga tablica może mieć w obu przypadkach inne wartości po każdym wywowałniu, ponieważ są to wartości alternatywne. Najważniejsze, żeby w każdym wywowałaniu dane poszczególnej tablicy się powtarzały.

Coraz bardziej jednak dochodzę do wniosku, że muszę mieć coś skopane w kodzie pod względem logiki, ponieważ nie powtórzył się w identyczny sposób problem przedstawiony przeze mnie w pierwszym poście. Tylko jakimś dziwnym trafem linuks to ogarnia...

ObrazekObrazek

Autor:  Palvanen [ 19 gru 2018, o 20:04 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Z tymi strukturami to pewnie by było dobre rozwiązanie tylko sęk w tym, że w przypadku zależności rozpisanych na 2,1k linii kodu ciężko to teraz uaktualnić. Ale w momencie jak pisałem o tym 0x30 dla zera (ze względu na typ char) przyszedł mi do głowy pewien pomysł.
Polegał on na tym, aby zamiast od razu ładować chary do tablicy, zmienić typy tablic na int i do tablic pakować faktycznie przeliczone dane liczbowe odpowiadające znakom tablicy ASCII. I dopiero to przerabiać w drugiej kolejności na char.
Napisałem taką protezę do funkcji, która oprócz przeliczania do dwóch tablic powołuje jeszcze jedną tablicę (dodatkowa tablica, bo powstała proteza) gdzie przekształca to co przeliczyła z intów na chary. I dopiero to wypluwane jest na ekran.
No i noga chudego bociana, jak ręką odjął.
Być może faktycznie gdzieś w obliczeniach dzieje się coś dziwnego, co powoduje, że chce upakować do tablicy chara, którego nie potrafi zidentyfikować, może jakieś kodowanie znaków ma coś wspólnego - niby proste ASCII...

Jakie wnioski? Hmm... Jak narazie to chyba takie, że jak dużo złożonych rzeczy się robi i chce się uzyskać prawidłowy program na Windows/Linux jednocześnie, to lepiej jechać na liczbach. A jak chcemy mieć znaki, to dopiero później bawić się w konwersje.
Język C naprawdę jest pełen niespodzianek.

Dziękuję serdecznie wszystkim za pomoc i być może będzie kiedyś okazja, aby i mi udało się w czymś pomóc.
Ale mimo wszystko oby kodzenie szło każdemu tak, żeby tych problemów było jak najmniej.

Jeśli ktoś jakąś opinią chciałby się podzielić, to chętnie bym poczytał. A jak nie, to temat do zamknięcia?

Autor:  Lex_ [ 19 gru 2018, o 23:43 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Konwersji dokonujesz przez rzutowanie typów ? Coś musiało być zamieszane, być może mieszały się typy.
Z czystej ciekawości napisałem sobie coś takiego:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Różne typy i różne wartości. A tutaj wyniki - raczej zaskoczenia dużego brak:
Obrazek

W ostatnim wypadku jedynie pokusiłem się o rzutowanie inta na typ char tak już nieco fantazyjnie :)
Typ int ma conajmniej 2 bajty więc od razu tablica się rozrasta, choć potem i tak skracasz to do 1 bajta (typ char). Elastyczność typów to czasami miecz obosieczny w C.
Ciekawe jednak, że program pod windowsem się wykrzaczał a linuxem sobie radził.

Pozdrawiam.

Autor:  andrews [ 20 gru 2018, o 09:13 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Nie gniewajcie się koledzy, ale trochę mi to przypomina wykłady profesora "mniemanologii stosowanej" ;) Trudno jest rozważać błędy w kodzie, którego się nie widziało na oczy. Ja rozumiem, że przedstawienie do analizy na forum kodu zawierającego tysiące linii nie jest dobrą praktyką, ale zawsze można wydzielić problem do osobnego projektu, ograniczając kod do minimum, przy którym jeszcze błąd występuje.

Skoro już jednak próbujemy zgadnąć przyczynę problemu, to chciałbym zwrócić uwagę na pewien fakt. Standard C definiuje różne podstawowe typy danych:
  • char
  • signed char
  • unsigned char
To czy liczba jest ze znakiem, czy bez znaku, ma dla kompilatora kluczowe znaczenie przy doborze odpowiednich instrukcji asm.
To czy typ char zostanie potraktowany jako signed czy unsigned jest "machine dependent", ale może też być wymuszone przez opcje kompilatora -fsigned-char i -funsigned-char. Dobrą praktyką, szczególnie w przypadku pisania kodu, który ma być przenośny, jest jawne oreślenie "signedness" typu char, czyli deklarowanie zmiennych zawsze jako signed char lub jako unsigned char.

Bez kodu nie wiadomo, jakie operacje są wykonywane na elementach tablicy, więc to tylko zgadywanka, ale spróbowałbym zadeklarować jawnie typ char jako signed lub unsigned.

Sądząc po tej wypowiedzi:
Palvanen napisał(a):
...przyszedł mi do głowy pewien pomysł.
Polegał on na tym, aby zamiast od razu ładować chary do tablicy, zmienić typy tablic na int i do tablic pakować faktycznie przeliczone dane liczbowe odpowiadające znakom tablicy ASCII. I dopiero to przerabiać w drugiej kolejności na char.
Napisałem taką protezę do funkcji, która oprócz przeliczania do dwóch tablic powołuje jeszcze jedną tablicę (dodatkowa tablica, bo powstała proteza) gdzie przekształca to co przeliczyła z intów na chary. I dopiero to wypluwane jest na ekran.
No i noga chudego bociana, jak ręką odjął.
coś może "być na rzeczy" ;)

EDIT:
To jeszcze bardziej przemawia za moją teorią:
Palvanen napisał(a):
z ciekawości chciałem wykonać kompilację na innej platformie systemowej.
Ponieważ nie mam aktualnie dostępu do własnego komputera, do takich celów mam w swoim telefonie zainstalowany emulator z Arch Linux for amr i zainstalowanym gcc. Wykonałem kompilację i uwaga... Działa...

W kodzie dla x86 typ char jest zwykle traktowany jako signed char, a na platformę ARM - jako unsigned char.

Autor:  mirekk36 [ 20 gru 2018, o 10:08 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

andrews napisał(a):
Nie gniewajcie się koledzy, ale trochę mi to przypomina wykłady profesora "mniemanologii stosowanej" Trudno jest rozważać błędy w kodzie, którego się nie widziało na oczy. Ja rozumiem, że przedstawienie do analizy na forum kodu zawierającego tysiące linii nie jest dobrą praktyką, ale zawsze można wydzielić problem do osobnego projektu, ograniczając kod do minimum, przy którym jeszcze błąd występuje.

Nic dodać, nic ująć ;) ... dlatego ja nie włączałem się nawet (niestety) do tej dyskusji ... bo tak można sobie właśnie ... pisać, pisać zgadywać, wróżyć, gadać ... ot taka pogaducha ;)

Autor:  czarekgr [ 23 gru 2018, o 09:19 ]
Tytuł:  Re: [C] Znikająca wartość tablicy

Spróbuj wyłączyć wszelkie optymalizacje kompilatora, góra -O2 , może coś z tym jest.

Strona 1 z 1 Strefa czasowa: UTC + 1
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/