2010-04-22 13 views
5

Mam następujący fragment fragmentuAlokacja stosu nie powiedzie się i alokacja sterty zakończy się sukcesem! Czy to możliwe?

Class Sample 
{ Obj_Class1 o1; 
    Obj_Class2 o2;}; 

ale wielkość Obj_Class1 i Obj_Class2 jest tak ogromny, że kompilator pokazuje ostrzeżenie „Zastanów się, trochę miejsca na kupie”. Zostałem poproszony o zastąpienie Obj_Class1 o1 z Obj_Class1* o1 = new Obj_Class1(); Ale uważam, że nie ma sensu wprowadzanie tej zmiany, ponieważ alokacja sterty również zakończy się niepowodzeniem, jeśli alokacja stosu zakończy się niepowodzeniem. Mam rację? Czy ma sens wprowadzenie tej zmiany (innej niż wyłączenie ostrzeżenia kompilatora).

+0

Po prostu z ciekawości, jaka jest wielkość zajęć? – Naveen

+0

około 65000 bajtów ... – Prabhu

+0

Zamiast zamiast zamieniać instancję Obj_Class1 na wskaźnik, czy zamiast tego można zmienić jej implementację, aby zamiast tego alokować swoje potrzeby na stercie? Nawet zmiana go na Pimpl może pomóc. –

Odpowiedz

5

Jest bardzo typowy, że stos jest mniejszy niż sterty. Używają różnych lokalizacji pamięci. Stos ma zwykle rozmiar około megabajta (można go zmienić, ale należy zachować ostrożność) i jest przydzielany dla każdego wątku. Sterty mogą zużywać gigabajty w razie potrzeby.

+0

Ale stos i sterta rosną przeciwko sobie. Czy oni nie? – Prabhu

+0

@Prabhu: Tak, ale maksymalny rozmiar stosu jest nadal ograniczony do czegoś podobnego do 1 megabajta. – sharptooth

+0

@Prabhu: Nie, nie robią tego. To dobry model wyjaśnienia dla klasy informatycznej, ale w rzeczywistości nic nie zmusza tego modelu do tego, którego faktycznie używa. –

3

Stos jest zwykle mały i nie nadaje się do przechowywania olbrzymich przedmiotów, a sterty są oddzielne i przeznaczone dla nich.

W swojej próby, powinieneś przeznaczyć cały Sample na stercie, a nie jej członkowie:

int main() { 
    Sample* sample = new Sample(); 
} 
2

W przypadku visual studio, każdy wątek domyślnie otrzymuje 1 MB przestrzeni, a jeśli spróbujesz przydzielić więcej, niż otrzymasz błąd przepełnienia stosu. Stert nie ma tego ograniczenia, a ilość pamięci, którą można przydzielić, zależy od największej ciągłej dostępnej przestrzeni w pamięci wirtualnej procesu. Nic więc dziwnego, że alokacja stosów kończy się niepowodzeniem, jeśli obiekty są naprawdę ogromne.

+0

Nitpick: przepełnienie stosu nie występuje przy przydzielaniu wartości większej niż wielkość stosu, ale raczej przy alokowaniu więcej niż dostępny rozmiar stosu. Mam na myśli, że to się nie zawiedzie w zależności od tego, ile stosu jest już zużyty. – sharptooth

3

Stack jest raczej mały domyślnie: http://msdn.microsoft.com/en-us/library/ms686774(VS.85).aspx

Domyślny rozmiar zarezerwowanej i początkowo popełnione pamięci stosu jest określony w nagłówku pliku wykonywalnego. Tworzenie wątków lub włókien kończy się niepowodzeniem, jeśli brakuje pamięci do zarezerwowania lub zatwierdzenia żądanej liczby bajtów. Domyślny rozmiar rezerwacji stosu używany przez linker wynosi 1 MB. Aby określić inny domyślny rozmiar rezerwacji stosu dla wszystkich wątków i włókien, należy użyć instrukcji STACKSIZE w pliku definicji modułu (.def). System operacyjny zaokrągla określony rozmiar do najbliższej wielokrotności granularności alokacji systemu (zazwyczaj 64 KB). Aby uzyskać szczegółowość alokacji bieżącego systemu, użyj funkcji GetSystemInfo.

Powiązane problemy