2016-02-19 13 views
5

Come si dice che 8 mb di stack sono dati a ciascun processo. Questo stack verrà utilizzato per memorizzare le variabili locali. Quindi, se prendo un array di dimensioni massime rispetto allo stack, deve overflow ??Straripante pila con enorme variabile locale?

int main() 
{ 
int arr[88388608]; 
int arr1[88388608]; 
int arr2[88388608]; 
while(1); 
return 0; 
} 

Ma non riesco a ottenere il risultato!

+2

Quando si eccede nello stack si ottiene * un comportamento non definito * che a volte può sembrare funzionare come previsto. Inoltre, i compilatori in questi giorni sono piuttosto intelligenti. Dato che quegli array non sono utilizzati, perché il compilatore dovrebbe effettivamente creare spazio per loro? –

+0

Cosa succede quando cambi il tipo di arr da 'int' a' volatile int'? –

+2

Inoltre, AFAIK, le dimensioni dello stack possono variare su sistemi diversi. –

risposta

5

Benvenuti nel mondo dei compilatori di ottimizzazione!

A causa della regola as-if, al compilatore è richiesto solo di creare qualcosa che avrebbe gli stessi risultati osservabili del codice originale. Quindi il compilatore se a:

  • rimuovere le matrici inutilizzati
  • rimuovere il loop vuoto
  • memorizzare le matrici dinamiche dall'esterno principale della pila - perché principale è una funzione speciale che viene chiamato solo una volta dall'ambiente

Se si desidera osservare l'overflow dello stack (quello cattivo, non il nostro bel sito :-)), è necessario:

  • utilizzare il codice per riempire gli array
  • compilare con tutti i ottimizzazione rimosso e richiamo in modalità di debug per dire al compilatore fare quello che ho scritto nel modo più accurato possibile

Il seguente codice fa SIGSEGV con clang 3.4.1 quando compilato come cc -g foo.c -o foo

#include <stdio.h> 

#define SIZE 88388608 

void fill(int *arr, size_t size, int val) { 
    for (size_t i=0; i<size; i++) { 
     arr[i] = val; 
    } 
}  
int main() { 
    int arr[SIZE]; 
    int arr1[SIZE]; 
    int arr2[SIZE]; 

    fill(arr, SIZE, 0); 
    fill(arr1, SIZE, 0); 
    fill(arr2, SIZE, 0); 
    printf("%d %d %d\n", arr[12], arr1[15], arr2[18]); 

    return 0; 
} 

e anche questo codice funziona bene quando compilato come -O2 livello di ottimizzazione ... compilatori sono ora a o intelligente per me, e non sono abbastanza coraggioso da guardare a fondo il codice assembly che sarebbe l'unico vero modo per capire cosa viene effettivamente eseguito!

+0

@Lingxi: la tua risposta era quasi corretta. Se lo traduci in C e lo annulli (e mi ping in un commento) lo inviterò perché il mio è solo una spiegazione intorno al tuo –

Problemi correlati