C++ przydział dynamiczny a wskaźnik na typ char

0

Witam !
Chciałbym się dowiedzieć jednej rzeczy a mianowicie :
W jednej z książek do C++ za każdym razem gdy używamy wskaźnika na typ char potem dynamicznie przydzielamy mu pamięć.
char * s;
s=new char[len];
Jest to dosyć oczywiste jednakże MVS pozwala mi na zadeklarowanie wskaźnika i od razu przypisania do niego ciągu bez wcześniejszego przydziału pamięci :
char * s;
s= "Ssss";
Więc, jak to wygląda w tym drugim przypadku ? Czemu mam taką możliwość, czy pamięć jest automatycznie przydzielana i zwalniana ? Jeśli tak to po co zazwyczaj sami dynamicznie przydzielamy pamięć ?

1

Pamięć przydzielana dynamicznie na stercie i trzeba zrobić delete:

char *s =new char[len];

Pamięć przydzielana na stosie czyli automatycznie usuwana gdy będzie niepotrzebna:
Ot zwykły cstring

const char *s = "Ssss";

:)

0

No dobrze, czyli w drugim przypadku pamięć jest przydzielana i zwalniana automatycznie, więc jaki jest w tym haczyk ?
Przecież o wiele łatwiej w klasach było by mi się posługiwać drugim przypadkiem i nie martwić się wtedy o konstruktor kopiujący, operator przypisania itd. Jednakże wszystkie przykłady zamieszczone w książce są robione z dynamicznym przydziałem pamięci(albo string), czemu odrzucamy tą drugą opcje ? Jedyne co mi przychodzi do głowy to biblioteka string, ale wtedy czemu nie możemy cały czas używać string'a tylko robimy to pierwszym sposobem ?

4

Dobre pytanie. Literały tekstowe (czyli w twoim przypadku "Ssss", ale pamiętaj, że to const char*) znajdują się w pamięci przez cały czas, nie są nigdy zwalniane. Kompilator i linker w MSVC umieszczają tego typu dane w sekcji ".rdata" pliku wykonywalnego (rdata - read only data). Pamięć na nią jest alokowana przez sam system operacyjny podczas ładowania/uruchamiania pliku wykonywalnego.

Sekcję ".rdata" możesz sobie podejrzeć w programach typu PE explorer, a w trakcie uruchomionego już programu w prawie każdym debuggerze.
user image
user image

1

@grzesiek51114 albo

 const char *s = "Ssss";

albo

 char s[] = "Ssss";

żeby uniknąć takich błędów: http://kaczus.ppa.pl/art/Skrzynia_porad,18.html#test_char

0

Czyli używając literałów tekstowych(const char*) zapycham pamięć, bo nie są one zwalniane podczas wykonywania programu przez co mój program może nie być wydajny, tak ? A przydzielając pamięć dynamicznie unikam tego. A czy używając obiektów string które posiadają chyba mechanizmy(new i delete) zarządzające pamięcią efektywnej, też jest to mniej opłacalne pod względem wydajnościowym niż jeśli sami dynamicznie przydzielimy i zwolnimy pamięć ? Np. jeśli w przyszłości pisał bym jakieś projekty dla firm to musiałbym wszędzie dynamicznie przydzielać pamięć, czy mógłbym ułatwić sobie prace i używać string'a ?(wiem, że pewnie w zależności od firmy było by inaczej, ale chciałbym wiedzieć czy te wszystkie literały tekstowe i stringi są zrobione tylko po to żeby ułatwić pracę na początku a i tak potem każdy doświadczony programista sam zarządza pamięcią dynamicznie czy w przyszłości też się je wykorzystuje?)

0

I jeszcze jedna uwaga odnośnie konstrukcji char s[] = "Ssss";. Tutaj Ssss nadal jest literałem w sekcji .rdata, ale zmienna s znajduje się oczywiście na stosie, do której za każdym razem nasz literał będzie kopiowany (tak, kopiowany!).

@TCK: oczywiście, że nie zapychasz pamięci, bo tak czy siak żeby skorzystać z tych twoich literałów muszą się one znaleźć w pamięci. Używanie i literałów i std::stringów jest jak najbardziej naturalne i nie ma w nich nic złego, mało optymalnego czy niestosowanego.

0

Tutaj ktoś ładnie wytłumaczył: http://stackoverflow.com/questions/4970823/where-in-memory-are-string-literals-stack-heap

Czy będzie niewydajny? Nic z tych rzeczy, a dynamicznej alokacji pamięci poprzez new trzeba używać rozsądnie, choćby dlatego, że sterta jest wolniejsza od stosu, a i o zwolnieniu pamięci łatwo później zapomnieć. Gdzie się da używaj zmiennych alokowanych na stosie. Nie oznacza to, że dynamicznej alokacji pamięci w C/C++ trzeba unikać. Nic z tych rzeczy.

Możesz spokojnie używać literałów i nawet wiele funkcji C ich wymaga. Nie unikniesz ich raczej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1