Allocation de mémoire pour le programme C

Programme

#include int a=10; void main() { int i=0; printf("global = %p, local = %p\n",&a,&i); main(); } 

Sortie

 mohanraj@ltsp63:~/Advanced_Unix/Chapter7$ ./a.out global = 0x804a014, local = 0xbfff983c global = 0x804a014, local = 0xbfff980c . . . global = 0x804a014, local = 0xbf7fac9c global = 0x804a014, local = 0xbf7fac6c global = 0x804a014, local = 0xbf7fac3c Segmentation fault (core dumped) mohanraj@ltsp63:~/Advanced_Unix/Chapter7$ 

Le programme ci-dessus obtient une erreur de segmentation. Parce que le get principal s’appelle récursivement. Ce qui suit est l’allocation de mémoire à un programme C.

allocation de mémoire

  __________________ __________________ | | | | | stack | | Main | | ↓ | |----------------| ------------------ | Main | | | |----------------| |  | |----------------| ------------------ | Main | | | |----------------| | ↑ | | Main | | Heap | |----------------| | | | Main | | | |----------------| __________________ |////////////////| ---> Collision occurs. So, Segmentation fault Occurs. | | |________________| | data | | data | __________________ |________________| | text | | text | __________________ |________________| Figure(a) Figure(b) 

Donc, je m’attends à ce qui est montré comme dans la figure (b), l’appel principal de manière récursive. Si elle atteint le segment de données, la collision se produit. Si cela se produit, il n’ya plus d’espace disponible pour la fonction principale. Donc, il obtient une erreur de segmentation. Donc, en utilisant le programme ci-dessus, je l’expérimente. Sur ce programme, l’adresse de la variable globale ‘a’ est “0x804a014”. Chaque fois que main est appelée, la variable locale “i” est déclarée. Donc, j’attends, avant la faute de segmentation, que l’adresse de i soit proche de ‘a’. Mais, les deux adresses sont très différentes. Alors qu’est-ce qui se passe ici?

Pourquoi l’adresse de ‘a’ et ‘i’ n’est pas dans la même plage au moment de l’erreur de segmentation de l’erreur. Alors, comment vérifier si le principal atteint la taille de la stack et est saturé?

Votre schéma est un modèle conceptuel ou une implémentation possible. Mais par exemple, un programme multithread aura une stack par thread et un seul tas, ce qui ne correspond pas vraiment à votre schéma simplifié.

Tout ce qui est requirejs, c’est que le système permette la récursivité, ce qui signifie que chaque nouvel appel d’une fonction obtient une copie privée des variables locales. Tout ce qui rest dépend de la mise en œuvre.

L’affectation récente de la page à l’utilisation du système, et un processus reçoit généralement un ensemble de segments de page, mais ils ne sont pas nécessairement consécutifs, et vous pouvez avoir des trous entre eux lorsqu’un access SIGSEGV se produit (violation de segment)

TL / DR: vous programmez plus probablement un signal SIGSEGV que l’adresse de la variable dynamic atteignant l’adresse statique – vous devriez trouver une ancienne boîte MS / DOS pour afficher un tel comportement …

“a” est une variable globale et elle ne sera pas en stack. Ce sera dans la section de données – c.-à-d. Initialisé bss

‘i’ est une variable locale et sera stocké dans la stack.

Ce sont des sections entièrement différentes et donc la différence.

S’il vous plaît se référer à la gestion de la mémoire globale en C ++ en stack ou en tas?

Lorsque vous écrivez la variable “i” est déclaré , vous écrivez quelque chose de correct, mais la variable n’est pas déclarée comme globale a .

i stack allouée et la stack a sa propre taille.

ulimit peut changer cette limite.

Ce que vous essayez de voir, la collision entre l’allocation d’adresses d’une variable globale et une variable locale , n’est pas possible.

Le modèle de mémoire que vous avez est une énorme simplification excessive qui n’est utile que pour commencer à enseigner les bases de la mémoire aux étudiants pour ne pas les submerger de détails au début. Tout comme nous commençons l’éducation mathématique avec l’ajout de nombres naturels. C’est un bon fondement mais cela ne vous mènera pas loin si vous utilisez juste cela pour comprendre la réalité.

Ce modèle n’a pas été précis depuis au moins 25-30 ans et ne peut être utilisé pour faire des prédictions sur le comportement réel du programme. Il peut y avoir des dizaines, voire des milliers, d’autres mappages de mémoire entre le tas et la stack (bibliothèques partagées, grands mallocs, fichiers mmap, etc.). Le concept de “tas” est très problématique car souvent, il n’est pas beaucoup plus que la sum de toutes les allocations dynamics de mémoire anonyme n’importe où dans l’espace d’adresse à des fins que le système d’exploitation ne connaissait pas auparavant.

Ce qui se passe dans votre exemple, c’est que vous courez dans la limite des ressources de la stack (voir ulimit -s ).