_LM_ Napisano Lipiec 21, 2021 Udostępnij Napisano Lipiec 21, 2021 (edytowany) Pisząc drobne programiki na AVR w C nie był możliwy taki konstrukt: int w = 10; // przykład, w może oznaczać rozmiar ciągu danych np: z uart char str[w]; Tymczasem działając teraz z programem pod esp8266 tak z ciekawości napisałem: int packetSize = Udp.parsePacket(); char packetBuffer[packetSize]; Pytanie teraz do ekspertów: czy powyższy zapis jest prawidłowy? to się kompiluje i działa ale czy nie powinienem zastosować jakichś funkcji do dynamicznej alokacji danych? Edytowano Lipiec 21, 2021 przez _LM_ Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Lipiec 22, 2021 Udostępnij Lipiec 22, 2021 O ile pamiętam to jest rozszerzenie gcc (w C też to potrafi). Jeśli nie planujesz zabawy z innymi kompilatorami albo z parametrami typu --pedantic możesz to zostawić. Możesz również np. zrobić tablicę o maksymalnej długości pakietu, użyć malloc/new albo (jeśli nie chcesz sobie zawracać głowy zwalnianiem pamięci) spróbować alloca (uwaga, bo to taka trochę dziwna funkcja). Ja bym to zostawił albo zrobił tablicę o określonej długości. 1 Cytuj Link do komentarza Share on other sites More sharing options...
_LM_ Lipiec 22, 2021 Autor tematu Udostępnij Lipiec 22, 2021 Podziękował Cytuj Link do komentarza Share on other sites More sharing options...
Matthew11 Lipiec 22, 2021 Udostępnij Lipiec 22, 2021 Jak mówimy o C++ i kompilator ma dostępny C++11 to możemy wykorzystać dobrodziejstwa smart pointerów (a konkretnie std::unique_ptr) do dynamicznej alokacji, żeby potem nie musieć ręcznie zwalniać pamięci. auto charArray = std::unique_ptr<char[]>(new char[10]); std::unique_ptr ma metodę get(), która zwraca klasyczny wskaźnik do zaalokowanego zasobu. Pełny przykład: #include <memory> #include <iostream> class Test { public: Test() { std::cout << "ctor\n"; } ~Test() { std::cout << "dtor\n"; } }; int main() { auto testArray = std::unique_ptr<Test[]>(new Test[3]); auto charArray = std::unique_ptr<char[]>(new char[10]); } Jak mamy dostępny C++14 to możemy użyć std::make_unique zamiast tzw. naked new (po prostu chodzi o operator new): auto charArray = std::make_unique<char[]>(10); Jest też taki konstrukt jak placement new - możemy wykorzystać jakiś statyczny bufor i nam stworzyć jakiś obiekt - wtedy nie ma problemów z dynamiczną alokacją. 2 Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
_LM_ Lipiec 23, 2021 Autor tematu Udostępnij Lipiec 23, 2021 Jak zwykle pełna profeska Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Lipiec 23, 2021 Udostępnij Lipiec 23, 2021 Nie jestem pewien, czy alokowanie pamięci na stercie to dobry pomysł. Jest jednak duża różnica między pierwszymi programami, gdzie tablica była alokowana na stosie, a ostatnią wersją - może to ładnie w wygląda w C++, ale działać może o wiele gorzej. Cytuj Link do komentarza Share on other sites More sharing options...
Matthew11 Lipiec 23, 2021 Udostępnij Lipiec 23, 2021 23 minuty temu, Elvis napisał: Nie jestem pewien, czy alokowanie pamięci na stercie to dobry pomysł. Oczywiście w zależności od przypadku użycia możemy na wszystko odpowiedzieć "to zależy". Natomiast w tym konkretnym przypadku - czyli zapisywaniu odebranych danych w jakimś buforze - prawdopodobnie najlepszą opcją pozostaje skorzystanie ze statycznego bufora. Nie mniej kiedy, nie mamy innej możliwości i pozostaje tylko dynamiczna alokacja pamięci i dodatkowo mamy dostępny C++11 wtedy inteligentne wskaźniki są według mnie bezpieczniejszą opcją niż użycie naked new/delete (czy malloc/free) - mniej wycieków pamięci i mniej problemów z ręcznym jej zwalnianiem. Cytuj Link do komentarza Share on other sites More sharing options...
_LM_ Lipiec 23, 2021 Autor tematu Udostępnij Lipiec 23, 2021 (edytowany) 13 minut temu, Matthew11 napisał: Natomiast w tym konkretnym przypadku - czyli zapisywaniu odebranych danych w jakimś buforze - prawdopodobnie najlepszą opcją pozostaje skorzystanie ze statycznego bufora Czy to oznacza że mam jednak z góry określić rozmiar bufora? W tym konkretnym programie funkcja obsługi udp jest używana tylko w czasie wprowadzania nastaw urządzenia, następnie esp jest resetowany i przy uruchamianiu w trybie normalnym nie powołuję już obiektu udp. Dlatego wszystkie zmienne są tymczasowe i nic nie jest udostępniane na zewnątrz. Tj oprócz struktur które i tak są globalne dla całego programu które to z kolei zapisują i odczytują dane z eeprom Edytowano Lipiec 23, 2021 przez _LM_ Cytuj Link do komentarza Share on other sites More sharing options...
Matthew11 Lipiec 23, 2021 Udostępnij Lipiec 23, 2021 2 minuty temu, _LM_ napisał: Czy to oznacza że mam jednak z góry określić rozmiar bufora? Tak jak napisał @ethanak jeśli nie będziesz zmieniał kompilatora (np. pod MSVC tego nie skompilujesz) lub nie będziesz używał flag, które wyłączają rozszerzenia (--pedantic) możesz zostawić program tak jak jest. Ja mimo wszystko użyłbym tablicy o wystarczającym do tego zadania rozmiarze - raczej jesteś w stanie określić jaki rozmiar będzie miał pakiet. 1 Cytuj Link do komentarza Share on other sites More sharing options...
_LM_ Lipiec 23, 2021 Autor tematu Udostępnij Lipiec 23, 2021 1 minutę temu, Matthew11 napisał: raczej jesteś w stanie określić jaki rozmiar będzie miał pakiet. Oczywiście to nie jest problem. Rozwiałeś moje wątpliwości Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Lipiec 23, 2021 Udostępnij Lipiec 23, 2021 Albo użyć alloca 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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!