• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak działa przepełnienie stosu w C++?

VPS Starter Arubacloud
0 głosów
684 wizyt
pytanie zadane 4 czerwca 2021 w C i C++ przez wojtek_suchy Mądrala (6,880 p.)

Cześć!
Co zadeklarowane przeze mnie ląduje na stosie a co nie?

#include <bits/stdc++.h>

using namespace std;

const int MILION = 1e6;

void rec(int i){
    if (i == 0)
        return;
    int niecenzuralne_slowo = 420 * 2137;
    return rec(i-1);
}

int main(){
    int n[MILION * 3];                      // powoduje przepelnienie
    rec(MILION);                            // powoduje przepelnienie
    int a[MILION], b[MILION], c[MILION];    // nie powoduje przepelnienia
    vector<int> vec(MILION * 69);           // nie powoduje przepelnienia
    int m;
    return 0;
}

Ten stos jest w trakcie programu zwalniany? Mógłby ktoś napisać coś o tym, albo podesłać jakiś link bo nie rozumiem jak to działa.

2 odpowiedzi

+1 głos
odpowiedź 4 czerwca 2021 przez adrian17 Ekspert (344,100 p.)
wybrane 4 czerwca 2021 przez wojtek_suchy
 
Najlepsza

Co zadeklarowane przeze mnie ląduje na stosie a co nie?

Wszystko zadeklarowane w funkcji, co nie alokuje pamięci dynamicznie.

Mógłby ktoś napisać coś o tym, albo podesłać jakiś link bo nie rozumiem jak to działa

https://en.wikipedia.org/wiki/Stack-based_memory_allocation

https://pl.wikipedia.org/wiki/Stos_(informatyka)#Stos_procesora

int a[MILION], b[MILION], c[MILION];    // nie powoduje przepelnienia

Na oko: bo kompilator jest sprytny i zauważył że te tablice nie są używane, więc skleił je w jedną tablicę o rozmiarze miliona. Jak wziąłem adresy tych tablic (co zmusiło kompilator do stworzenia osobnych tablic), to dostałem przepełnienie.

    int a[MILION], b[MILION], c[MILION];
    auto ptr = &a; ptr = &b; ptr = &c;
13:26 $ g++  -g main.cpp && ./a.out 
Segmentation fault (core dumped)

A to:

vector<int> vec(MILION * 69);

Po prostu dlatego, że vector alokuje pamięć normalnie na stercie, a na stosie dochodzi tylko kilkanaście bajtów na wskaźniki z których składa się vector.

0 głosów
odpowiedź 4 czerwca 2021 przez profesorek96 Szeryf (91,420 p.)

Po pierwsze każdy program ma coś takiego jak stos i stertę. W C++ mamy cztery rodzaje pamięci:

  • pamięć automatyczna - zwykłe zmienne deklarowane w funkcji, żyją do wyjścia z bloku kodu lub funkcji, same są zwalniane. Te zmienne trafiają na stos.
  • pamięć dynamiczną - wszystko co jest deklarowane za pomocą operatora new lub funkcji malloc, calloc dla języka C. Pamięć tego rodzaju na nasze życzenie jest alokowana, na nasze życzenie jest zwalniana, jeśli tego nie zrobimy to dojdzie do wycieku pamięci. Pamięć alokowana jest na stercie, zaś na stosie przechowujemy jedynie wskaźnik do tej pamięci.
  • pamięć statyczną - zmienne globalne, tworzone ze słowem static.
  • pamięć wątku

 

Polecam poczytać sobie ten artykuł:

http://simplemesimpleit.pl/index.php/10-c/9-c-blok-obszary-rodzaje-pamieci-stos-sterta-static-bss-data-code-text

Musisz wiedzieć że w programach standardowy rozmiar stosu to zazwyczaj 1MB zaś to wszystko zależy od kompilatora. Twój problem polega na tym że nie jest możliwe stworzenie tak dużej tablicy która będzie zmienna automatyczną. Tablica ta będzie tworzona na stosie, rozmiar stosu jest zbyt mały by pomieścić tablicę. Spróbój użyć vectora lub tablicy dynamicznej.

komentarz 4 czerwca 2021 przez Oscar Nałogowiec (29,290 p.)
Trochę pomięszane. Słówko static nie umieszcza zmiennej w pamięci statycznej - tam są wszystkie zmienne globalne. Te ze słówkiem static są widoczne tylko w ramach jednostki kompilacji - nie podlegają linkowaniu.

Rozmiar stosu nie jest tak prosto zależny od kompilatora - przecież uruchamiany program musi dostać jakiś stos już przed wykonaniem pierwszej instrukcji, bo inaczej nie mógłby nawet wywołać funkcji do jego zmiany.
komentarz 4 czerwca 2021 przez profesorek96 Szeryf (91,420 p.)
Owszem słowo static powoduje że zmienna jest widoczna tylko w tej jednostce kompilacji. Jednak to nie tylko jedno zastosowanie tego słowa kluczowego. Tak da się zmieniać rozmiar stosu, jednak z tego co znalazłem na szybko pisząc tą odpowiedź to zależy od kompilatora.

https://stackoverflow.com/questions/1825964/c-c-maximum-stack-size-of-program
komentarz 5 czerwca 2021 przez tkz Nałogowiec (42,000 p.)
Zależy od systemu, to on przydziela pamięć. Kompilator jest tylko gościem. Druga odpowiedź nawet to potwierdza.

Podobne pytania

0 głosów
0 odpowiedzi 135 wizyt
pytanie zadane 24 września 2022 w Systemy operacyjne, programy przez Patrykosik88 Początkujący (340 p.)
0 głosów
1 odpowiedź 191 wizyt
pytanie zadane 14 listopada 2021 w C i C++ przez pawel_000 Początkujący (450 p.)
0 głosów
2 odpowiedzi 1,952 wizyt
pytanie zadane 13 listopada 2016 w C i C++ przez ewazdomu Początkujący (320 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...