Sans rapport avec NULL... au sens du langage C.Envoyé par |PaRa-BoL
Thierry
Sans rapport avec NULL... au sens du langage C.Envoyé par |PaRa-BoL
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
bonsoir,
oui, ça n'a rien à avoir avec le problème de la discussion posé sur "NULL"..mujigka a écrit :
Sans rapport avec NULL... au sens du langage C.Citation:
|PaRa-BoL a écrit :
Et /dev/null c'est un trou noir ?
Thierry
@Emmanuel Delahaye : bah tu as la répense concernant ta question !:
++oui biensur, je précise..
- IDE : turbo C++ v4.5 (sous win biensur)
- OS : win XP SP2
- j'ai rien changé comme réglages, il est installé par défaut..
Envoyé par Blue_Strike
il ne pointe nul part :autrement dit y a pas de case memoire reservée pour un pointeur NULL.
mais plutot un pointeur NULL vaut en principe 0 mais cette case n'est pas reservée pour les variable.
important: on sait q'un pointeur vaut NULL par sa valeur (0)
pas par ce que contient l'adresse (0).
stddef.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 #if defined(__cplusplus) #define NULL 0 #else #define NULL ((void *)0)
Oui, on le sait bien. Et ?Envoyé par |PaRa-BoL
Et rien, je confirme juste par un quote le message précédent...
Alors il faut apprendre à citer :Envoyé par |PaRa-BoL
![]()
bonsoir,
mais elle existe qd même !denoo a écrit :
il ne pointe nul part :autrement dit y a pas de case memoire reservée pour un pointeur NULL.
mais plutot un pointeur NULL vaut en principe 0 mais cette case n'est pas reservée pour les variable.
important: on sait q'un pointeur vaut NULL par sa valeur (0)
pas par ce que contient l'adresse (0).
+9999
ça c'est au niveau soft ! je parle réellement qu'est ce qui se passe, vous me comprenez ?! (niveau architecture plus que soft)
bon j'ai une question : si un pointeur pointe sur une variable int par exemple, l'adresse de ce pointeur se trouve où ? c'est à dire où elle est stockée ?
et si un pointeur vaut NULL, autrement dit (0), est ce que celà est l'équivalent à 0000x0000 ??
@denoo : tu appelle quoi une case qui n'est pas reservée pour les variables ?
++
Pas forcément. Ca dépend des machines. Et si il y a une MMU ou pas etc. Le 0 de la MMU n'est pas le 0 physique...Envoyé par Blue_Strike
Il peut aussi en exister un grand nombre, comme en x86 mode réel modèle de mémoire small (DS:0000) avec DS valant de 0 à 0xFFFF
Le pointeur étant une variable, il a une adresse. Une adresse est une expression constante. Elle n'est pas 'stockée'. Vu de l'assembleur (langage machine), c'est une valeur immédiate.bon j'ai une question : si un pointeur pointe sur une variable int par exemple, l'adresse de ce pointeur se trouve où ? c'est à dire où elle est stockée ?
En valeur, oui, en adresse physique, non, pas automatiquement. C'est vrai dans certains cas.et si un pointeur vaut NULL, autrement dit (0), est ce que celà est l'équivalent à 0000x0000 ??
De la mémoire libre (heap ou tas ou free store). C'est la zone allouable par malloc().@denoo : tu appelle quoi une case qui n'est pas reservée pour les variables ?
+1Emmanuel Delahaye a écrit :
Pas forcément. Ca dépend des machines. Et si il y a une MMU ou pas etc. Le 0 de la MMU n'est pas le 0 physique...Citation:
Blue_Strike a écrit :
mais elle existe qd même !
ça existe en motorola aussi (68000)..Il peut aussi en exister un grand nombre, comme en x86 mode réel modèle de mémoire small (DS:0000) avec DS valant de 0 à 0xFFFF
oui mais même la valeure immédiate est "stocké" disons sauvegardée qque part non ?!Le pointeur étant une variable, il a une adresse. Une adresse est une expression constante. Elle n'est pas 'stockée'. Vu de l'assembleur (langage machine), c'est une valeur immédiate.dans la RAM par exeple, sinon, si tu mets :
int *k;
int i=59;
*k=i;
printf("%p",k); => ça doit afficher l'adresse de i, mais qui est reprentée par k, alors là, comment le compilateur trouve la valeur? ou coment il a connu que k est l'adresse de i ? sûrement qque chose a changé en executant cette instruction : *k=i;
Ok pour le reste
++
Soit ce petit programme:Envoyé par Blue_Strike
Il produit la sortie suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <stdio.h> #include <stdlib.h> void affiche_pile(void) { int a = 10; int *pa = &a; int *pb = NULL; printf("Adresse de a: %p\tValeur de a: %d\n", (void *)&a, a); printf("Adresse de pa: %p\tValeur de pa: %p\n", (void *)&pa, (void *)pa); printf("Adresse de pb: %p\tValeur de pb: %p (i.e %ld)\n", (void *)&pb, (void *)pb, (long)pb); } int main(void) { affiche_pile(); return EXIT_SUCCESS; }
On y voit que les valeurs de a, pa et pb sont stockées sur la pile aux adresses 0xbfaec314, 0xbfaec310 et 0xbfaec30c respectivement. On voit très clairement que pa pointe sur a. La valeur stockée dans pb à l'adresse 0xbfaec30c est NULL, c'est à dire 0x00000000 sur ma machine où les pointeurs sont codés sur 32 bits. Si tu regarde le code assembleur généré (dans mon cas par gcc), tu peux voir que ce ne sont que des valeurs binaires codées sur 4 octets.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 thierry@mujigka:~/forum$ ./forum Adresse de a: 0xbfaec314 Valeur de a: 10 Adresse de pa: 0xbfaec310 Valeur de pa: 0xbfaec314 Adresse de pb: 0xbfaec30c Valeur de pb: (nil) (i.e 0)
Voici le code assembleur GNU correspondant à la fonction affiche_pile():
Tu peux voir qu'il n'y a pas de différence entre la valeur 10 stockée dans a, qui dans le programme C est de type int, et la valeur 0 (i.e. NULL) stockée dans pb. Autrement dit, le types des variables n'existe plus dans ce code assembleur. Rien ne dit que la valeur à l'adresse -12(%ebp) (qui correspond ici à pb) est un pointeur et que cette valeur correspond à une adresse qui peut être déréférencée. C'est le compilateur qui décide si on peut déréférencer cette valeur, et génère le cas échéant le code assembleur permettant d'accéder à la valeur située à l'adresse stockée dans pb. Dans le cas, du pointeur NULL, le compilateur sait que ce n'est pas une adresse valable et son comportement est indéterminé.
Code gas : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 affiche_pile: pushl %ebp movl %esp, %ebp subl $40, %esp # Ici, on stocke la valeur 10 dans a movl $10, -4(%ebp) # On calcul l'adresse de a et on stocke cette valeur dans le # registre EAX (architecture IA-32) leal -4(%ebp), %eax # On stocke l'adresse de a dans pa movl %eax, -8(%ebp) # Et maintenant, on stocke la valeur 0 (NULL) dans pb movl $0, -12(%ebp) #...
Pour conclure, tout ceci fait apparaître que NULL correspond à la valeur 0x00000000 (sur mon PIII) et que cette valeur est dans le cas de notre exemple, stockée sur la pile. Ainsi NULL n'est qu'une valeur comme la valeur 10 stockée dans la variable a, mais ne pointe NULLE PART. C'est le compilateur qui décide si cette valeur peut représenter une adresse mémoire ou pas (lr compilateur sait que 10 n'est pas une adresse, car la valeur stockée dans a est de type int). Dans le cas de NULL, cela ne représente pas une adresse valable. Par suite, la question de savoir où pointe NULL est un non sens.
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Attend toi à des surprisesEnvoyé par Blue_Strike
![]()
Elle est écrite en dur dans le code machine. Il y a des champs de bits pour ça dans les instructions. Ouvrir son livre d'assembleur...Envoyé par Blue_Strike
Comme dirait ma fille 'explositiondans la RAM par exeple, sinon, si tu mets :
int *k;
int i=59;
*k=i;' k est un pointeur non initialisé, son déréférencement invoque un comportement indéterminé. Tout le raisonnement de la suite est faux.
J'ai l'impression que la manipulation des pointeurs n'est pas très claire pour toi. Dans le micro bout de code ci-dessus, jamais le pointeur k ne reçois l'adresse de i. *k = i; correspond à un déréférencement de k (non initialisé i.e. comportement indéfini) pour stoquer la valeur de i à l'adresse contenue dans k. C'est pas du tout ce que tu décris. Regarde mon dernier post et tu comprendras mieux...Envoyé par Blue_Strike
Voici ce que donne la sortie console:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <stdio.h> #include <stdlib.h> void comprendre_mem(void) { int i = 59; int *k; /* Ici, k reçoit l'adresse de i de manière explicite */ k = &i; printf("L'adresse de k: %p\tContenu de k: %p\n", (void *) &k, (void *) k); printf("L'adresse de i: %p\tContenu de i: %d\n", (void *) &i, i); } int main(void) { comprendre_mem(); return EXIT_SUCCESS; }
Et voici l'assembleur généré pour la fonction comprendre_mem():
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 L'adresse de k: 0xbfceae60 Contenu de k: 0xbfceae64 L'adresse de i: 0xbfceae64 Contenu de i: 59
Il n'y a absolument aucune magie nulle part! k est une variable située sur la pile qui contient une valeur qui correspond à l'adresse de i. L'emplacement mémoire de i est ici situé 4 "cases plus haut" que k. Ainsi, à l'adresse de k (0xbfceae60), on trouve bien la valeur 0xbfceae64 qui correspond à l'adresse de la variable i située 4 octets plus "haut".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 comprendre_mem: pushl %ebp movl %esp, %ebp subl $40, %esp # La valeur 59 est stockée sur la pile dans la valiable i movl $59, -4(%ebp) # L'adresse de i est calculée et sa valeur est plcée dans EAX leal -4(%ebp), %eax # L'adresse de i est copiée dans sur la pile dans k movl %eax, -8(%ebp) # Toute la suite concerne printf() movl -8(%ebp), %eax movl %eax, 8(%esp) leal -8(%ebp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf movl -4(%ebp), %eax movl %eax, 8(%esp) leal -4(%ebp), %eax movl %eax, 4(%esp) movl $.LC1, (%esp) call printf leave ret
Thierry
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Partager