C++: mity i fakty

W latach 90. rozpowszechniła się w kręgach zainteresowanych tematyką opinia, że język C++ nie nadaje się do tego, żeby pisać w nim programy dla mikrokontrolerów jednoukładowych. W przypadku małych systemów 8- i 16-bitowych, dominujących w tamtym okresie, jest to zapewne prawda. Ale dziś, w dobie tanich mikroprocesorów 32-bitowych o wielkiej (w porównaniu do tych z poprzednich dekad) mocy przetwarzania i znacznych zasobach, można sobie zadać pytanie, na ile ta niezbyt pochlebna dla C++ opinia ma nadal pokrycie w faktach, a na ile jest utrzymującym się siłą inercji mitem.

Dodaj do ulubionych źródeł w Google
Posłuchaj
00:00
Spis treści

RTTI

Mechanizm RTTI (Run-Time Type Information, informacja o typie w trakcie wykonywania programu) pozwala na odnalezienie dokładnej informacji o typie danego obiektu, gdy do dyspozycji jest tylko wskaźnik lub odwołanie do typu bazowego. Taka definicja sugeruje, że RTTI będzie źródłem strat w wydajności działania kodu, ale tak nie jest. Jedyny koszt, jaki ponosimy, polega na tym, że do każdej klasy polimorficznej dodawany jest obiekt type_info, a one nie są duże - dla poniższego przykładu:

class Baza
{
public:
virtual ~Baza() {}
};
class Pochodna: public Baza {};
class DrugaPochodna: public Pochodna {};

Łączny rozmiar obiektów type_info dla klasy Druga- Pochodna wyniesie kilkadziesiąt (około 30) bajtów, o czym można się łatwo przekonać przy użyciu debuggera albo po prostu zaglądając do tekstu w asemblerze wygenerowanego przez kompilator. Wiele kompilatorów ma opcje wyłączające RTTI, co pozwala się łatwo pozbyć i tego narzutu.

Fragmentacja pamięci

Trudnością, której wystąpienia w niewielkich systemach mikroprocesorowych można nie przewidzieć, jest fragmentacja pamięci. W istocie jest to problem wspólny dla wszystkich systemów - małych i niedziałających na pamięci rzeczywistej, bez jej stronicowania i wirtualizacji adresów. Dotyczy to zwłaszcza systemów wielozadaniowych, ale nie tylko. W nowoczesnych systemach operacyjnych dla komputerów osobistych, serwerów itp. pamięć jest zwirtualizowana, problem fragmentacji nie występuje, a co za tym idzie, programiści są z nim na ogół nieobeznani i mogą nie pomyśleć o możliwości jego wystąpienia.

Fragmentacja jest nieuchronnym skutkiem ubocznym działania mechanizmu dynamicznej alokacji pamięci. Wyobraźmy sobie sytuację, kiedy procedura alokacji pobiera z systemu blok wolnej pamięci o zadanej wielkości i przydziela go programowi. Po jakimś czasie program żąda alokacji następnego bloku i dostaje go. Każda taka operacja powoduje, naturalnie, zmniejszenie się ilości wolnej pamięci.

Teraz, jeśli program zwolni pierwszy blok, ale zatrzyma sobie drugi, ilość wolnej pamięci formalnie wzrośnie o wielkość zwolnionego bloku, ale wolny obszar będzie teraz nieciągły: będą się na niego składać dwa mniejsze obszary ("fragmenty") przedzielone blokiem nadal zajętym przez program, a rzeczywisty, możliwy do alokacji obszar RAM-u zmniejszy się do wielkości równej wielkości największego fragmentu.

Na przykład, załóżmy, że początkowa ilość wolnej pamięci RAM w systemie to 1 MB. Program zajmuje blok nr 1 o wielkości 200 KB, potem blok nr 2 o wielkości 300 KB, a w następnej kolejności zwalnia blok nr 1. W tym momencie w systemie formalnie jest 700 KB wolnej pamięci pozostającej do dyspozycji programów, ale największy obszar możliwy do zajęcia pojedynczym wywołaniem malloc() ma już tylko 500 KB.

Asynchroniczna alokacja i dealokacja różnej wielkości bloków podczas działania programu będzie tę sytuację dalej pogarszać, prowadząc do stopniowego rozdrabniania - właśnie "fragmentacji" - obszarów wolnych na coraz mniejsze porcje. W końcu dojdzie do sytuacji, kiedy w systemie zabraknie wolnej pamięci mimo pozornej jej obfitości (ale będzie to np. 700 KB w 50 fragmentach, z których największy będzie miał np. 25 KB).

Co gorsza, negatywne skutki tego zjawiska mogą stać się widoczne dopiero po pewnym czasie: po wielu dniach lub nawet tygodniach nieprzerwanego działania systemu, przez co mogą umknąć uwadze programistów i testerów. W efekcie urządzenie, przeważnie działające bez zarzutu, będzie od czasu do czasu, bez widocznych przyczyn tajemniczo "padać".

Oczywistym - i w zasadzie jedynym - wyjściem z tej sytuacji jest stronicowanie pamięci i wirtualizacja adresów. Oczywiście w mikrokomputerach jednoukładowych, zwłaszcza małych, raczej nie można sobie na to pozwolić. W języku C - gdzie w zasadzie nic nie dzieje się bez wiedzy programisty - obchodzi się ten problem przez unikanie jak ognia użycia funkcji dynamicznej alokacji pamięci malloc() i free().

Często zresztą jest to łatwiejsze, niż mogłoby się na pierwszy rzut oka wydawać, bo zapotrzebowanie aplikacji na pamięć da się w bardzo wielu przypadkach ocenić bardzo dokładnie, co z kolei pozwala na jej przydział w postaci statycznych buforów o znanej z góry wielkości.

W C++ to samo podejście wymaga rezygnacji ze wspomnianych już powyżej funkcji new() i delete(), co, trzeba przyznać, jest większym poświęceniem niż rezygnacja z malloc() i free() w języku C. Można też spróbować ich reimplementacji tak, żeby zamiast przydzielać pamięć dynamicznie, przydzielały statyczne bufory o określonej z góry wielkości.

Chcesz częściej widzieć nasze artykuły w Google? Dodaj ElektronikaB2B do ulubionych źródeł
Spis treści
Powiązane treści
PRQA wprowadza narzędzie do analizy statycznej QA·C++ w nowej wersji V3.2
Zobacz więcej w kategorii: Technika
Zasilanie
Zasilacze impulsowe i przetwornice DC/DC oraz DC/AC o mocy od 10 W do 1 kW – parametry, zastosowania i kryteria doboru
Komunikacja
Qualcomm Technologies rozszerza ofertę układów SoC Wi-Fi do zastosowań w IoT
Projektowanie i badania
Badania EMC: dlaczego urządzenia zawodzą i jak przygotować się do certyfikacji?
Komponenty
Zarządzanie alternatywami w prototypowym BOM – klucz do niezawodnego montażu elektroniki
Elektromechanika
Kolej przyszłości napędzana elektroniką. Jak EMC, zarządzanie temperaturą i zasilanie decydują o niezawodności transportu szynowego
PCB
HDI pool Eurocircuits - mikroprzelotki w prototypach i małych seriach PCB
Zobacz więcej z tagiem: Artykuły
Magazyn
Październik 2026
Magazyn
Wrzesień 2026
Magazyn
Sierpień 2026

Zobaczyć obiekt oczami radaru, czyli dlaczego potrzebujemy laboratorium do pomiarów RCS?

Radar postrzega świat inaczej niż człowiek. Zamiast obrazu tworzonego przez światło widzialne rejestruje echo wysłanej fali elektromagnetycznej. Na odpowiedź radarową obiektu wpływają nie tylko jego rozmiary, lecz także kształt, zastosowane materiały, częstotliwość oraz kierunek obserwacji. Dlatego dwa przedmioty o podobnych wymiarach mogą być dla radaru widoczne zupełnie inaczej. Jak zatem sprawdzić, co radar rzeczywiście "widzi"? Służą temu pomiary RCS, prowadzone między innymi w specjalistycznych laboratoriach, które zapewniają kontrolowane i powtarzalne warunki oraz umożliwiają uzyskanie dokładności wymaganej w danym zastosowaniu.
Zapytania ofertowe
Unikalny branżowy system komunikacji B2B Znajdź produkty i usługi, których potrzebujesz Katalog ponad 7000 firm i 60 tys. produktów