Zastanawiałem się, czy istnieje jakakolwiek różnica (pod względem składni i wydajności) między zdefiniowanym łańcuchem
char str[200];
i
char *str;
str = calloc(200, sizeof(char));
Czy istnieją różnice w zakresie użytkowania? (na przykład jeden nie jest kompatybilny z strncpy
czy coś) Co ważniejsze, czy istnieją różnice w zakresie wydajności?
EDYTOWAĆ: Rozumiem, że tablica zdefiniowana przez char *
i calloc
może rosnąć i zmniejszać się, ale czy powinienem wybrać pamięć sterty nad pamięcią stosu lub odwrotnie z dowolnego powodu? Właśnie to naprawdę chciałem zapytać.
Odpowiedzi:
4 dla odpowiedzi № 1char str[200]
przydzielone w pamięci stosu, gdzie jako calloc()
przydziela w pamięci sterty.
Z natury calloc (), przypisuje 0 do wszystkich przydzielonych przez niego bajtów.
Pls odnoszą się do następującego porównania stosu i stosu
Co jest szybsze: alokacja stosu lub alokacja sterty
http://www.linuxquestions.org/questions/programming-9/stack-faster-than-heap-685004/
3 dla odpowiedzi № 2
Czy istnieją różnice w zakresie użytkowania? (na przykład jeden nie jest zgodny z strncpy lub czymś)
Dziwię się, że nikt nie wspomniał, że pierwsza str. Tj. Nazwa tablicy ma wartość a stały wskaźnik i nie można zmienić przypisania, gdzie jako drugi jest zmienna wskaźnika które można ponownie przypisać.
Więc
char str[SIZE];
char * b = malloc(SIZE);
str = b; // This is a compilation error
b = str; // where as this is perfectly legal (ignoring the fact
// that we are losing malloced memory without actually freeing it)
1 dla odpowiedzi nr 3
Po pierwsze, przydziela pamięć na stosie, podczas gdy druga przydziela pamięć dynamiczną. pamięć stosu jest zarządzana automatycznie, a pamięć dynamiczna wymaga ręcznego zarządzania.
Kiedy masz wybór, zawsze powinieneś preferować pierwsze:
- Nie musisz pamiętać o uwolnieniu czegokolwiek
- pamięć dynamiczna ma niewielkie obciążenie pod względem wydajności.
Czy istnieją różnice w zakresie użytkowania? (np. jeden nie jest kompatybilny z strncpy lub czymś)
Pod względem użytkowania z funkcjami obie sąpodobnie, w prostym znaczeniu, podczas korzystania z funkcji oba są wskaźnikami wskazującymi kolejne bloki pamięci. Kiedy przekazujesz tablicę do działania, rozpada się ona jako wskaźnik na pierwszy element.
Różnica polega na tym, gdzie są przechowywane i czy są zarządzane automatycznie, czy zarządzane ręcznie.
1 dla odpowiedzi nr 4
char str[200];
- Jest prostą deklaracją (nie dynamiczną alokacją),
- Domyślnie są to śmieci,
- Szybki dostęp (w segmencie stosu),
Scope is local
(w ciągu {}).
char * str;
str = calloc (200, sizeof (char));
- Wszystkie wartości elementów są zerowe (ponieważ
calloc()
), - Wolny dostęp (wykorzystanie segmentu sterty),
- dynamiczne wykorzystanie alokacji, czyli efektywne wykorzystanie pamięci.
- Musisz wyraźnie usunąć alokację,
- Pamięć
Scope is global
, możesz wrócić np.return str
z funkcji`.
0 dla odpowiedzi № 5
Powinieneś używać alokacji stosu, gdy tylko jest to możliwe: jest łatwiejszy w utrzymaniu dla programisty i jest również mniej wymagający pod względem wydajności.
W wielu przypadkach alokacja stosu tablic nie jest możliwa.
- Jeśli w czasie kompilacji nie znasz rozmiaru swojej tablicy. Jednak najnowszy standard C ma pewne wsparcie dla tego,
- masz tablicę tablic, których rozmiar nie jest taki sam,
- potrzebujesz przydzielonej pamięci, aby się utrzymała po powrocie funkcji.
Zwróć też uwagę na to char str[200]
„Zna” jego rozmiar (tj. sizeof(str) == 200*sizeof(char)
) podczas gdy będziesz musiał zapamiętać wielkość przydzielonej tablicy w zmiennej pomocniczej, aby z nią pracować (sizeof(str) == sizeof(char*)
, zazwyczaj 4 lub 8).
-1 dla odpowiedzi № 6
Pamięć tablicy znaków jest przydzielana na stosie. gdy tylko sterowanie wyjdzie z funkcji zawierającej tablicę, pamięć jest zwalniana i nie można uzyskać dostępu do tablicy.
Podczas gdy funkcja calloc przydziela pamięć na stercie i pozostaje do momentu, gdy program zostanie uruchomiony, pamięć zostanie zwolniona ręcznie
-1 dla odpowiedzi № 7
Po utworzeniu ciągu nie ma różnicy w użyciu.
char str [100] przydziela ciąg na stosie, podczas gdy inne podejście używa sterty. Przydziały na stosie są zawsze szybsze niż na stercie (zobacz tę dyskusję: Co jest szybsze: alokacja stosu lub alokacja sterty)
Dodatkowo calloc () ustawia wszystkie elementy tablicy na 0 / NULL, jeszcze bardziej obniżając wydajność. Jeśli programujesz w C ++ i potrzebujesz użyć sterty, zawsze pisz:
char * str = new char [200];
Ma to dodatkowe korzyści, np. zgłoszenie błędu, jeśli sterta jest pełna.