Czy powinienem uczyć moich uczniów przydziałów? [Zamknięte]

18

Jak szeroko stosowany jest allocaw prawdziwym świecie? Czy powinienem uczyć moich uczniów używania, allocagdy ma to sens? Czy powinienem ich nauczyć, aby nigdy ich nie używali? Pochodzący z tła C ++ RAII pomysł, że nie trzeba freeręcznie wywoływać, brzmi obiecująco, szczególnie w funkcjach z wieloma punktami wyjścia.

fredoverflow
źródło
8
Dlaczego nie nauczyć ich VLA C99?
@cnicutar assigna () jest zależny od implementacji, ale co najmniej wiele implementacji zwraca NULL w przypadku niepowodzenia. C99 VLA nie mają możliwości wskazania awarii.
Skomplikowane patrz biografia,
2
@sbi: Dla SO jest to pytanie otwarte, które tak naprawdę nie pasuje do tego, co według osób zamykających powinno być postami SO. Jest to zbyt subiektywne, nie ma jednoznacznej odpowiedzi, jedynie opinia. Co jest w porządku, ale nie dla SO. Zauważ też, że z szacunku dla przedstawiciela PO nikt nie głosuje, po prostu zamykamy to pytanie jako nie na temat.
Paul Sasik,
1
@PascalCuoq Zresztą i tak nie powinieneś dużo przydzielać. Jeśli nie masz pewności, co „dużo” znajduje się w bieżącym kontekście, użyj malloc.

Odpowiedzi:

31

Jeśli prowadzisz kurs z ogólnego programowania C, nie powinieneś uczyć ich czegoś , co nie jest w standardzie. Początkujący programiści niepotrzebnie piszący niestandardowy i / lub nieprzenośny kod, ponieważ zostali w ten sposób nauczeni, był ogromnym problemem dla branży oprogramowania w ciągu ostatnich 20-30 lat. Koszt nie uczenia ich standardu i nic poza standardem jest prawdopodobnie astronomiczny.

Jeśli prowadzisz bardziej zaawansowany kurs algorytmów lub programowania aplikacji, warto o tym wspomnieć. Z drugiej strony programowałem wszystko, od twardych aplikacji osadzonych w czasie rzeczywistym do puchu aplikacji Windows przez 15 lat bez użycia tej funkcji.


źródło
Jedynym zastosowaniem, jakie widziałem, gdy nie byłoby lepiej zrobić inaczej, było wykrywanie rozbicia stosu w niektórych wersjach systemu Windows, gdzie brak alokacji wskazywał na niewystarczającą ilość miejsca - a może po prostu miał trochę ASM do złapania awarii ; minęło trochę czasu, odkąd spojrzałem na ten kod. Działało, ale było trochę przerażeniem.
Donal Fellows
13

Widzę dwie rzeczy:

  1. Uczniowie rozumieją wpływ alloca, czytają o różnicach między stosem a stosem i używają go allocaostrożnie. (mało prawdopodobne)

  2. Uczniowie myślą: „wow, to jest jak mallocbez martwienia się o free”, używaj go nadmiernie, dostajesz przepełnienie stosu i nie mam pojęcia, co jest grane.

Myślę, że jest znacznie lepiej, jeśli opisujesz alloca, a następnie uruchom ten kod:

#include <malloc.h>

int OverflowMyStack(int start) {
    if (start == 0)
        return 0;

    char * p = (char *)_alloca(4096);
    *p = '0';
    return OverflowMyStack(start - 1);
}

int main () {
    return OverflowMyStack(512);
} 

Źródło: http://www.strchr.com/alloca

pokaż im niebezpieczeństwa, a następnie powiedz, żeby ich nie używali. Nadal będą się uczyć o stosie a stercie, zobaczą niebezpieczeństwa w akcji i będą mogli przejść do standardowych rzeczy.

Maczuga
źródło
1
Myślę, że większość uczniów nadal zalicza się do drugiej kategorii, nawet po pokazaniu im przykładowego kodu.
prawej strony
@WTP - Prawdopodobnie, ale dlatego mówisz im, aby nie używali go nawet po pokazaniu im, co może się zdarzyć.
BlackJack
4
Dlaczego ten kod używa, _allocaa nie alloca? I dlaczego to rzuca wynik?
Keith Thompson,
5

Odpowiedź na to pytanie powinna opierać się przede wszystkim na twoich celach .

Czy chcesz nauczyć kogoś, kto już umie programować, jak pisać C i pracować z istniejącym kodem C w środowisku naturalnym? Jeśli tak, powiedz o alokacji i wszystkim, czego chcesz.

Z drugiej strony, jeśli prowadzisz kurs wprowadzający, w którym używa się C tylko przez przypadek (a ponieważ C jest bardzo małym językiem itd.), Powinieneś skupić się na ważnych częściach (pisanie programów modułowych, podprogramów, kolekcji itp. .). Z perspektywy studenta alokacja jest zbędna, ponieważ w większości przypadków wystarcza malloc, a z punktu widzenia dobrego kodu lepiej wyraźnie wspomnieć o tym, jak ręczne zarządzanie pamięcią jest denerwujące i jak inne języki radzą sobie z tym problemem. W końcu jest więcej rzeczy do zarządzania pamięcią, a następnie alokacją lub RAII, więc naprawdę nie powinieneś ograniczać się do nich, a jak już wspomniałeś, o wiele łatwiej jest zrozumieć cel alokacji, jeśli porównasz go z innymi „bardziej standardowymi” sposobami robienia rzeczy w innych językach (lub C99 ...)

hugomg
źródło
2

Nie.

Jedynym powodem, dla którego programista C powinien być świadomy istnienia przydziału, jest zrozumienie i poprawienie używającego go starszego kodu.

Każde użycie allocajest albo

  1. Bezużyteczne, tzn. Można go w prosty sposób zastąpić zmiennymi o stałym rozmiarze o automatycznym czasie przechowywania, LUB
  2. Niebezpieczne przepełnienie stosu czeka na wystąpienie.

Oprócz kilku eksperymentów myślowych, dla których nigdy nie znalazłem żadnych przykładów w świecie rzeczywistym, nie ma przypadku użycia alloca(lub VLA), który nie byłby ani bezużyteczny, ani wrażliwy (jeden z powyższych 2 przypadków).

R .. GitHub ZATRZYMAJ LÓD
źródło
2
Oczywiście absolutnie nikt nigdy nie byłby w stanie odpowiedzialnie z niego korzystać. Nie, nigdy.
DeadMG,
Jedyne „odpowiedzialne” użycie allocjest w 100% równoważne z automatycznymi tablicami o stałej wielkości i mniej przenośne.
R .. GitHub ZATRZYMAJ LÓD
Sądzę więc, że nikt nigdy nie będzie chciał przydzielić jakiejś dynamicznej kwoty, powiedzmy, kilku kilobajtów, które nigdy się nie przepełniły. Lub wywołaj funkcję API systemu operacyjnego, która powie im, ile jest dostępnych. Lub po prostu znacznie zwiększ rozmiar stosu.
DeadMG,
Jeśli jest to kilka KB i jesteś pewien, że masz kilka KB, możesz po prostu użyć T foo[5000];lub cokolwiek innego.
R .. GitHub ZATRZYMAJ LÓD
Tylko jeśli T ma trywialny domyślny konstruktor. Gdybym potrzebował wydajności, nawet proste zerowanie pamięci może mnie kosztować. Ale inne typy mogą mieć jeszcze bardziej złożoną logikę budowy domyślnej. Gdybym chciał na przykład dynamicznie utworzyć tablicę std::mutex, mógłbym wywołać wywołanie jądra i przełącznik kontekstu dla pięciu tysięcy muteksów. Nie tanie. Nie wspominając o dodatkowych kosztach pamięci podręcznej umieszczania zmiennych lokalnych po tablicy.
DeadMG,
1

Moim zdaniem nie zachęcam do korzystania z niego, chyba że uczysz zasad kompilatora niskiego poziomu używanych do przydzielania miejsca na stosie dla zmiennych lokalnych. Naucz tego w tym kontekście.

MartyTPS
źródło
0

Dokumentacja GCC ma kilka praktycznych zalet i wad alloca(). Z praktycznego punktu widzenia korzysta z niego spora ilość wolnego oprogramowania, więc dobrze jest zrozumieć, jak działa i gdzie jest używany w istniejącym kodzie.

Przekazywanie -Wl,-stack=nowego rozmiaru stosu do gcc zwiększa maksymalny rozmiar stosu; musisz to zrobić, jeśli Twój projekt używa alloca()lub przydziela duże tymczasowe tablice lub używa rekurencji poza określoną głębokość zależną od kontekstu.

użytkownik117529
źródło