2010-11-19 11 views
7

Ten kod daje mi błąd segmentacji około 1/2 czasu:Segmentacja ze względu na brak pamięci w C

int main(int argc, char **argv) { 
    float test[2619560]; 
    int i; 
    for(i = 0; i < 2619560; i++) 
     test[i] = 1.0f; 
} 

I rzeczywiście trzeba przeznaczyć znacznie większy wachlarz, czy istnieje jakiś sposób pozwalając system operacyjny, aby uzyskać więcej pamięci?

używam Linux Ubuntu 9.10

Odpowiedz

22

Jesteś przepełnione domyślny maksymalny rozmiar stosu, który wynosi 8 MB.

Możesz zwiększyć rozmiar stosu - np. do 32 MB:

ulimit -s 32767 

... czy można przejść do alokacji z malloc:

float *test = malloc(2619560 * sizeof test[0]); 
+2

Jeśli korzystasz z funkcji malloc, możesz sprawdzić kod, jeśli alokacja się powiodła - znacznie lepiej niż przy alokacji z nadzieją, że się nie zawiesza. (addendum, nie tyle komentarz @ cas) –

+2

@Sam Dufel Należy pamiętać, że niektóre systemy (np. linux domyślnie) mogą zwrócić ci nie-zerowy wskaźnik z malloc, nawet jeśli nie masz pamięci - co prowadzi do podobnych awarii, gdy próbujesz uzyskać dostęp do tej pamięci. – nos

+0

To chyba bardziej dokładne stwierdzenie, że niektóre systemy oddzielają pojęcia przydzielania wirtualnej przestrzeni adresowej i zatwierdzania magazynu kopii zapasowych. – caf

6

Teraz jesteś alokacji (lub przynajmniej próbuje) 2619560*sizeof(float) bajtów na stosie. Przynajmniej w większości typowych przypadków stos może wykorzystywać tylko ograniczoną ilość pamięci. Można spróbować zdefiniowaniem static zamiast:

static float test[2619560]; 

to pobiera go z komina, więc może to zazwyczaj użyć dowolnej dostępnej pamięci zamiast. W innych funkcjach definiowanie czegoś jako static zmienia semantykę, ale w przypadku main robi małą różnicę (poza teoretyczną możliwością rekursywnego main).

+0

Rekurencyjne 'główne', co? Brzmi interesująco. – You

+0

@ You: Czasami używany w IOCCC lub code golf. W przeciwnym razie, nie tak bardzo (i niedozwolone w C++). –

0

To jest stos overflower. Lepiej użyć funkcji malloc, aby uzyskać większą pamięć niż rozmiar stosu, który można uzyskać z "ulimit -s".

1

Nie kładź tak dużego przedmiotu na stosie. Zamiast tego należy rozważyć przechowywanie go w stercie poprzez przydzielenie za pomocą funkcji malloc() lub jego przyjaciół.

Pływaki 2.6M to nie tyle, a nawet w systemie 32-bitowym powinno być dobrze, jeśli chodzi o przestrzeń adresową.

Jeśli potrzebujesz przydzielić bardzo dużą tablicę, pamiętaj, aby użyć systemu 64-bitowego (zakładając, że masz wystarczającą ilość pamięci!). Systemy 32-bitowe mogą adresować tylko około 3G na proces, a nawet wtedy nie można przydzielić go jako pojedynczego bloku.

Powiązane problemy