2011-12-03 28 views
7

W systemie Linux, używając C, załóżmy, że mam dynamicznie określony n określający liczbę elementów, które muszę przechowywać w tablicy (int my_array[n]) przez krótki czas, na przykład, jedno wywołanie funkcji, w którym wywoływana funkcja wykorzystuje tylko małą pamięć (kilkaset bajtów).Rozmiar pozostałego stosu do wystąpienia przepełnienia stosu

Przeważnie n to niewiele, kilka dziesiątych. Ale czasami n może być duży, aż 1000 lub 1 000 000 000.

Jak obliczyć, czy mój stos może pomieścić n*o + p bajtów bez przepełnienia?

Zasadniczo: ile bajtów zostało na moim stosie?

+0

możliwy duplikat [Sprawdzanie dostępnego rozmiaru stosu w C] (http://stackoverflow.com/questions/53827/checking-available-stack-size-in -c) –

+0

@BrendanLong, Widziałem to pytanie, ale jak stwierdza: "Używam MinGW z GCC 3.4.5 (mingw-special vista r3)", odpowiedzi są nieco skoncentrowane na Windowsie. Moje pytanie brzmi: Linux/* nix wyśrodkowany. ;-) – kay

+0

dlaczego nie możesz użyć 'getrusage()' i 'getrlimit()'? – sverre

Odpowiedz

4

Rzeczywiście, pytanie checking available stack daje dobrą odpowiedź.

Ale bardziej pragmatyczna odpowiedź brzmi: nie przydzielaj dużych ilości danych na stosie wywołań.

W twoim przypadku można obsługiwać inaczej przypadek, gdy n<100 (a następnie przeznaczając na stosie, może thru alloca, sens) oraz przypadek, gdy n>=100 (wtedy przeznaczyć na stercie z malloc (lub calloc) i nie zapomnij o tym free). Ustaw próg stały na 100 a #define.

Typowa ramka połączenia na call stack powinna być, na obecnych laptopach lub komputerach stacjonarnych, najwyżej kilobajtami (a najlepiej mniej, jeśli masz rekursję lub wątki). Całkowita ilość miejsca na stosie wynosi zwykle najwyżej kilka megabajtów (a czasem znacznie mniej: w jądrze stosy mają zwykle po 4 KB).

+1

Mieszanie 'calloc' i' alloca' to zła wiadomość, ponieważ jedna inicjuje dane, a druga nie. Może to potencjalnie wprowadzić dziwne błędy. – Dave

+2

OK, może to być 'malloc' i' alloca'. –

4

Jeśli nie używasz wątków, lub jeśli wiesz, że Twój kod wykonywany na głównym stosie, a następnie

  1. Record bieżący wskaźnik stosu przy wejściu głównym
  2. W swojej rutyny, uzyskać aktualne ograniczenie stosu (zobacz man getrlimit)
  3. Porównaj różnica między bieżący wskaźnik stosu i zanotowanego w kroku 1 z limitem od kroku 2.

Jeśli używasz i zagrożeń, ds i może być wykonywany na wątku innym niż główny, zobacz man pthread_getattr_np

Powiązane problemy