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

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!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

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