Kiedy używasz stderr w C?


Najlepsza odpowiedź

Zakładam, że wiesz, że kiedy uruchamiasz program w C, masz 3 otwarte pliki, dwa z nich mają nazwę STDOUT i STDERR, zwykłe komunikaty przechodzą na standardowe wyjście (tj. gdy wywołujesz printf), a komunikaty o błędach na stderr (gdy wywołujesz na przykład fprintf (stderr, …), te dwa (faktycznie otwarte pliki) są bezpośrednio połączone przez twój system operacyjny do twojego terminala, będącego terminalem Unix lub terminalem Windows. Najważniejszą ich cechą jest to, że mogą być przekierowywane, na przykład w Uniksie, kiedy robisz: ls | grep plik.txt powłoka przekierowuje standardowe wyjście w „ls” i teraz miejscem docelowym tego wyjścia jest STDIN w procesie „grep”, więc grep może szukać wzorców w tym strumieniu, itd. To jest potężna rzecz, wiele filtrów uniksowych (właściwie programów) jest budowanych w ten sposób, który jest potężny.

EDYCJA: dodaj bardziej znaczący przykład Pozwól, że dodam nowe i bardziej wyraźne użycie przekierowania, abyś mógł uchwycić to na bardziej znaczącym przykładzie, spójrz na to polecenie:

curl http://ftp.gnu.org/gnu/wget/wget-1.17.1.tar.xz | xzcat – | tar xvf –

Tutaj curl zaczyna pobierać wget z projektu GNU, podczas gdy curl pobiera dane zapisuje do STDOUT, ale powłoka przekierowała standardowe wyjście curl na stdin z xzat, powłoka wykonuje to samo, przekierowuje standardowe wyjście xzcat na standardowe wejście tar i tar zaczyna dekompresować dane, niesamowite!

Odpowiedź

Po pierwsze, ogólna zasada: nie ważne co zrobisz, malloc() nigdy nie jest wywoływane automagicznie.

Kiedy deklarujesz struct, deklarujesz typ. Typ sam w sobie, nie zużywa pamięci w czasie wykonywania.

Kiedy deklarujesz zmienną typu struct, alokowana jest do niej pamięć, ale nie używa malloc(). Jeśli zmienna jest lokalna do funkcji, pamięć jest zwykle przydzielana na stosie. To po części sprawia, że ​​rekurencyjność jest możliwa w C: za każdym razem, gdy wywołujesz funkcję (nawet jeśli jest wywoływana z samej siebie), wskaźnik stosu jest dostosowywany i nowe miejsce jest zarezerwowane na stosie dla loc wszystkie zmienne tej funkcji i za każdym razem, gdy funkcja jest zamykana, stos jest „rozwijany”, a całe to miejsce jest zwolnione.

Kiedy deklarujesz zmienną globalną, jest dla niej dokonywana statyczna alokacja stos podczas uruchamiania programu, a zmienna pozostaje dostępna przez cały czas wykonywania programu. Wymagany rozmiar sterty jest znany w czasie kompilacji.

W przeciwieństwie do tego, gdy używasz malloc(), pamięć jest dynamicznie przydzielana programowi w czasie wykonywania przez system operacyjny i jesteś odpowiedzialny za uwolnienie go za pomocą free(), albo twój program (zwłaszcza jeśli jest to program działający przez długi czas bez restartu, np. aplikacja usługowa) będzie cierpieć z powodu wyciek pamięci, wpływający na wydajność i, w skrajnym przypadku, pozbawiający cały system zasobów. Użycie malloc() jest najbardziej odpowiednie, gdy a) wymagana ilość pamięci jest większa niż może być przydzielona na stercie lub stosie, lub b) wymagana ilość pamięci nie jest znane z góry.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *