Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Deklaracja tablicy string o rozmiarze zmiennej

Ostatnio zmodyfikowano 2014-10-07 13:54
Autor Wiadomość
qwers
Temat założony przez niniejszego użytkownika
Deklaracja tablicy string o rozmiarze zmiennej
» 2014-09-20 22:23:11
Dlaczego w C++ nie można utworzyć tablicy typu string, czy np. Sprite z biblioteki SFML o rozmiarze zmiennej (czyli o zmiennej długości)?
Np.:
C/C++
int zmienna = 5;
string nazwa[ zmienna ];
Sprite nazwa[ zmienna ];
Próba kompilacji skończy się otrzymaniem komunikatu błędu np. dla zmiennej string - " variable length array of non-POD element type 'string' ".

Wiem, że aby utworzyć tablicę string/Sprite, itp. o rozmiarze zmiennej należy tego dokonać w oparciu o dynamiczne przydzielanie pamięci:

C/C++
int zmienna = 5;
string * nazwa = new string[ zmienna ];
nazwa[ 0 ] = "a 8";
nazwa[ 1 ] = "c j o";
nazwa[ 2 ] = "t 0";
nazwa[ 3 ] = "kjbrgk ";
nazwa[ 4 ] = "** &";

cout << nazwa[ 0 ] << "+" << nazwa[ 1 ] << "+" << nazwa[ 2 ] << "+" << nazwa[ 3 ] << "+" << nazwa[ 4 ] << "\n";

1. Tylko dlaczego ten pierwszy zapis jest nieprawidłowy?
2. Co jest POD?
P-117257
SeaMonster131
» 2014-09-20 22:30:39
const int zmienna = 5;
P-117259
pekfos
» 2014-09-20 23:54:49
1. Nie można tak w ogóle robić, to nie należy do standardu języka C++. Od tego jest np std::vector<>
2. Plain Old Data - wygoogluj sobie.
P-117262
libed
» 2014-09-23 18:33:59
Każdy obiekt std::string to sizeof( std::string ) oraz pamięć dla samego stringa ( zazwyczaj większa niż długość ).
Moim zdaniem najlepiej przechowywać stringi jako tablice charów a konwertować na std::string tylko wtedy, kiedy potrzeba.

Osobiście jestem pedantem jeśli chodzi o zarządzanie pamięcią, a że ponoć vector z STL nawet nie próbuje użyć realloc() więc omijam go szerokim łukiem ;)
P-117389
Jacob99
» 2014-09-23 18:39:02
@libedI ronisz bardzo źle.
P-117391
pekfos
» 2014-09-23 18:50:47
@libedI ronisz bardzo źle.
Uzasadnij ;)
P-117393
akwes
» 2014-09-23 18:58:01
W celu wyjaśnienia zasadności używania realloc, aby nie dezorientować autora i nie uczyć go złych nawyków:

@libed, Twoje podejście jest typowo w stylu C.

Klasę std::string oraz std::vector zaprojektowano i zaimplementowano przez garść doświadczonych ludzi, którzy z wysokim prawdopodobieństwem uczyli te klasy bardziej optymalne niż dopieszczony kod szeregowego programisty kiedykolwiek zdoła być. std::vector jest niemalże (albo i dokładnie) tak samo (a może bardziej?) wydajny jak zwykłe tablice (mamy też jeszcze std::array).

Co więcej, w C++ nie tylko odchodzimy od używania malloc, realloc, free ale także operacji na surowych new i delete. C++ to szeroko pojęte RAII, gdzie tylko się da. Dlaczego? Ponieważ ilość błędów w kodzie znacząco spada przy zastosowaniu dobrodziejstw std::stringa i std::vectora, które ładnie i wręcz automatycznie zarządzają pamięcią.

Jeżeli jesteś pedantem w zarządzaniu pamięcią powinieneś doskonale wiedzieć jak ciężko dobrze napisać zarządzanie pamięcią w kodzie, który w wielu miejscach może rzucić wyjątek i spowodować masowe wycieki pamięci, tylko dlatego, że usuwanie zasobów jest w złym miejscu.

Podsumowując, po jednej stronie mamy czytelny, optymalny, bezpieczny i prosty kod a po drugiej stronie być może kod mniej pamięciożerny (być może, bo bez testów jest to wyłącznie gdybanie). Co więcej programiści (nawet dobrzy) często mylą się określając wąskie gardła programu i niepotrzebnie optymalizują kod, który w ogóle nie afektuje systemu.

Konkluzja: autorze, używaj std::vector i std::string i nie bój się o ich wydajność, jeżeli tylko używasz ich poprawnie.  
P-117396
libed
» 2014-09-24 00:38:52
@akwes: Oczywiście masz sporo racji.
Ad.1) Klasa std::string jest fajna i pomocna, jednak dalej uważam, że trzymanie łańcuchów w postaci std::string to marnotrawstwo pamięci. Tym bardziej jeśli owe dane wczytujemy/zapisujemy. Tak czy siak "obdzieramy" wtedy string z całej otoczki i wyłuskujemy sam łańcuch.
Z vectorem jest podobnie. Jest napisane tak, żeby pasował wszędzie i do wszystkiego. I tu pada pytanie "Czy lepszy jest ten co skacze przez płotki, pływa, strzela i biega ale we wszystkim jest przeciętny czy ten co tylko skacze ale za to rekordowo?" ;) Klasy STL są dobre ludzie je lubią bo ukrywają zabawę z wskaźnikami i pamięcią ( ni wiem dlaczego ludzie jej nie lubią! ) i taka jest "propaganda standardu" ;) Ale to wcale nie znaczy, że trzeba tego używać gdzie tylko się da.

Ad.2) Tak, jako obiekty tymczasowe spisują się świetnie ;)

Ad.3) Wyjątków unikam jak ognia. Moim zdaniem są one nadużywane i to trochę taki przerost formy nad treścią.

Ad.4) Prawdziwe optymalizacje to wyższa szkoła jazdy i redukcji pamięci używanej przez stringów nawet do nich nie zaliczam ;)

Ogółem moje podejście może być spowodowane tym, że nie trzymam się kurczowo obiektowości i łańcuchów znaków nie traktuje jak poważne obiekty. Służą mi jedynie do tego, żebym widział ludzki opis a nie ciąg cyferek. Nigdy stringi nie wpływają u mnie na control-flow programu, są jedynie ładnym opakowaniem danych. Dlatego też zazwyczaj wrzucam wszystkie do jednej struktury która tylko raz na początku alokuje wystarczającą ilość pamięci a następnie wrzucam do niej kolejno stringi, w programie operuję wyłącznie na indeksach.

Jak czytam najnowszy standard i obserwuje trendy to coraz częściej odnoszę wrażenie, że zamiast ułatwiać to on utrudnia programowanie.
Co ja poradzę. Nie widzę problemu w tym, aby obok variadic template strzelić wstawkę assemblerową :P Im mniej będzie nakazów używania tego a zakazywania tamtego, tym lepiej. Wszystko jest dla ludzi.
P-117404
« 1 » 2
  Strona 1 z 2 Następna strona