Skocz do zawartości

Tablice dynamiczne c++


_LM_

Pomocna odpowiedź

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 przez _LM_
Link do komentarza
Share on other sites

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.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

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ą.

  • Pomogłeś! 2
Link do komentarza
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

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

(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 przez _LM_
Link do komentarza
Share on other sites

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.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

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 

Link do komentarza
Share on other sites

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...

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.