Les éléments d’un tableau sont-ils garantis pour être stockés des adresses inférieures aux adresses supérieures?

Supposons que j’ai le tableau suivant:

int list[3]={2,8,9}; printf("%p,%p,%p",(void*)&list[0],(void*)&list[1],(void*)&list[2]); 

Est-il toujours garanti que & list [0] <& list [1] <& list [2] ?

J’avais supposé que c‘était une règle ssortingcte en utilisant C, mais je dois maintenant en être très sûr, car un OP me l’a demandé quand j’ai répondu à sa question sur l’ endianness

Petit endian ou Big endian

Ce qui m’a fait réfléchir, c’est que les stacks can grow up or down . Je ne suis pas très sûr de cela, alors vos réponses rigoureuses sont appréciées.Merci.

Oui, il est garanti que &list[0]<&list[1] et &list[1]<&list[2] . Lorsque des pointeurs sur des éléments du même tableau sont comparés, le pointeur sur l'élément dont l'indice est le plus grand est considéré comme ayant une valeur plus grande. Ceci est spécifié dans C99 6.5.8@5:

les pointeurs vers des éléments de tableau avec des valeurs en indice plus grandes comparent des points de vue supérieurs aux éléments du même tableau avec des valeurs en indice plus faibles

Cependant, il n'est pas garanti que les valeurs imprimées par printf avec %p suivront également le même ordre - ces valeurs sont définies par l'implémentation.

A partir de la norme C (“Section 6.2.5 Types”):

… Un type de tableau décrit un ensemble d’objects non vides alloués de manière contiguë …

Les tableaux seront alloués de manière contiguë en “mémoire”.

Ce que disent Eric et Interjay, ce que je n’avais pas pris en compte lors de la rédaction de cet article, merci Eric et Interjay, c’est que cela ne s’applique qu’aux adresses de mémoire virtuelle .

Votre machine et votre système d’exploitation utilisent très probablement une unité de gestion de la mémoire (MMU) qui crée un espace d’adressage virtuel (sur lequel vous travaillez) et le mappe sur la mémoire physique en blocs de la taille d’un bloc (pages).

Eric et Interjay disent donc que, bien que les adresses virtuelles soient contiguës, les blocs de mémoire physique qu’elles mappent peuvent se trouver à des adresses différentes.

  Virtual Physical +----------+ +----------+ | | | | VMA pg 1 |---------->| PMA 88 (VMA1) | | | +----------+ +----------+ | |\ ... | VMA pg 2 | \ ... | | \ ... +----------+ \ ... \ \ ... big gap in physical \ \ ... memory \ \ ... \ \ ... \ >--+----------+ \ | \ | PMA 999 (VMA2) \ | >-+----------+ 

Ainsi, pour les petits tableaux (plus petits que la taille de la page), cela peut être vrai pour les adresses VMA et PMA, bien que très probablement PMA! = VMA. Pour les tableaux de taille supérieure à la taille de la page, bien que VMA paraisse contigu, PMA peut être disjoint et en panne, comme le montre le diagramme ci-dessus …

De plus, je pense qu’Interjay et Eric vont encore plus loin en affirmant que toute adresse C, bien que contiguë dans le modèle C, puisse figurer n’importe où en mémoire. Bien que cela soit peu probable car la plupart des systèmes d’exploitation implémentent une sorte de pagination pour obtenir un mappage virtuel / physique, cela peut techniquement être le cas, je pense… c’était bien d’apprendre à envisager, alors merci chaps 🙂

Si vous demandez comment la mémoire apparaît dans le modèle C, les tableaux semblent contigus en code C et l’expression C &list[0] < &list[1] est vraie.

Si vous demandez comment la mémoire apparaît dans une implémentation C, le standard C ne nécessite aucune disposition particulière des tableaux en mémoire. La plupart des implémentations C utilisent une mémoire virtuelle ascendante consécutive pour les tableaux, mais les adresses descendantes seraient une simple variation. Et, au niveau de la mémoire physique, les tableaux ne sont généralement pas consécutifs, car le mappage de la mémoire virtuelle à la mémoire physique est déterminé par le système d'exploitation en fonction des ressources disponibles et peut même changer pendant l'exécution d'un processus.

De plus, rien ne garantit que les chaînes imprimées par %p sont des adresses de mémoire.