#176 Le 15/04/2010, à 21:29
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Raaah, Nausicäa vient de se finir :(:(.
C’est quoi ?
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#177 Le 15/04/2010, à 21:37
- grim7reaper
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Un anime du grand Miyazaki Hayao
Mais si un con me colle un NULL prématuré dans mon tableau de struct option*, il se passe un truc pas cool lors de l’appel à delete_option_table()…
Donc je ne sais pas si je dois être si fier de moi que ça. Mais bon, il suffit de mettre dans la doc que ce genre de comportement est strictement prohibé, c’est tout ?
Oui, tu ne peux guère faire mieux, donc documente le et puis c'est au dev de lire ta doc sinon tant pis pour lui.
Sinon, j’ai une solution pour que les noms des options restent explicite : demander à l’utilisateur de faire une énumération.
Ainsi, on aura opt_tab[verbose], ce qui reste tout à fait compréhensible.
C'est pas con ça . Remarque, si le mec réfléchit un minimum et veut un code clair, il y pense naturellement. Mais ça ne peut pas faire de mal de le préciser dans la doc.
Petit conseil pour tes fonctions de libération. Je les ferais plutôt comme ça
void delete_option(struct option** ptr)
{
free(*ptr);
*ptr = NULL;
}
void delete_option_table(struct option*** ptr)
{
int i;
for(i=0;(*ptr)[i]!=NULL;i++)
delete_option((*ptr)[i]);
free(*ptr);
*ptr = NULL
}
Ce petit ajout à un rôle que je trouve important.
Si le programmeur peu rigoureux réutilise le pointeur après sa libération il peut tout se passer comme rien du tout (celà dépend du système, il peut très bien relire ses données sans problèmes et s'il se limite à de la lecture ça peut passer inaperçu), or celà reste illégal et peut causer des bugs très dur à dépister (car caractère aléatoire, dépend de l'utilisation, du système, etc.).
Mais avec cette ajout, il va déréférencer du NULL et là ça va directement lui péter à la gueule via une SIGSEV et lui signaler qu'il a fait un truc pas réglo.
Tu vois la nuance ?
Wah, en utilisant mes nouvelles fonctions, comment que ça simplifie le code du programme de débug !
C'est le but mon cher
Dernière modification par grim7reaper (Le 15/04/2010, à 21:38)
Hors ligne
#178 Le 15/04/2010, à 22:11
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Ce petit ajout à un rôle que je trouve important.
Si le programmeur peu rigoureux réutilise le pointeur après sa libération il peut tout se passer comme rien du tout (celà dépend du système, il peut très bien relire ses données sans problèmes et s'il se limite à de la lecture ça peut passer inaperçu), or celà reste illégal et peut causer des bugs très dur à dépister (car caractère aléatoire, dépend de l'utilisation, du système, etc.).
Mais avec cette ajout, il va déréférencer du NULL et là ça va directement lui péter à la gueule via une SIGSEV et lui signaler qu'il a fait un truc pas réglo.
Tu vois la nuance ?
J’ai deux questions.
Premièrement, pourquoi c’est si important de demander l’adresse du pointeur pour ces fonctions ? Si j’ai bien compris, l’important c’est que le programmeur, en utilisant son pointeur déjà libéré, tombe sur du NULL et si prenne donc un SIGSEGV dans la tronche. D’ailleurs, on dit SIGSEGV ou SIGSEV ? Parce que dans le man de kill, j’ai trouvé SIGSEGV. Mais peut-être que cela se réfère à autre chose, je ne sais pas.
Donc en fait, là on oblige à passer une adresse, ce qui est déstabilisant, et je ne vois pas pourquoi.
Et voilà la deuxième question (vicieuse ) : pourquoi les devs de free() ne l’ont-ils pas fait ? Ça éviterait ceci, non ?
free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#179 Le 15/04/2010, à 22:21
- grim7reaper
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
J’ai deux questions.
Premièrement, pourquoi c’est si important de demander l’adresse du pointeur pour ces fonctions ?
Pour mettre NULL, quand tu veux modifier le contenu d'une variable tu passes son adresse, de la même manière quand tu veux modifier le contenu d'un pointeur tu passes son adresse.
Si j’ai bien compris, l’important c’est que le programmeur, en utilisant son pointeur déjà libéré, tombe sur du NULL et si prenne donc un SIGSEGV dans la tronche. D’ailleurs, on dit SIGSEGV ou SIGSEV ? Parce que dans le man de kill, j’ai trouvé SIGSEGV. Mais peut-être que cela se réfère à autre chose, je ne sais pas.
Non, c'est bien SIGSEGV (SIGSEV est une déformation dont je tente de me débarrasser, tout ça à cause d'une mauvaise lecture que j'ai traînée suffisamment longtemps pour que j'ai du mal à me corriger )
Donc en fait, là on oblige à passer une adresse, ce qui est déstabilisant, et je ne vois pas pourquoi.
Cf. avant, pour pouvoir modifier le contenu du pointeur (sinon faut faire un return NULL et faire confiance au gars pour qu'il le récupère et le mette lui-même dans son pointeur ).
Et voilà la deuxième question (vicieuse ) : pourquoi les devs de free() ne l’ont-ils pas fait ? Ça éviterait ceci, non ?
man free a écrit :free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
Pourquoi, ça, je l'ignore (il doit y avoir une bonne raison, ou au pire une raison historique), et oui ça éviterait le undefined behavior occurs, d'où l'intérêt de le faire soi-même.
Dernière modification par grim7reaper (Le 15/04/2010, à 22:36)
Hors ligne
#180 Le 15/04/2010, à 22:45
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Pylade a écrit :J’ai deux questions.
Premièrement, pourquoi c’est si important de demander l’adresse du pointeur pour ces fonctions ?
Pour mettre NULL, quand tu veux modifier le contenu d'une variable tu passes son adresse, de la même manière quand tu veux modifier le contenu d'un pointeur tu passes son adresse.
Quel con ! ><'
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#181 Le 15/04/2010, à 22:52
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
void delete_option_table(struct option*** ptr)
{
int i;
for(i=0;(*ptr)[i]!=NULL;i++)
delete_option(&(*ptr)[i]);
free(*ptr);
*ptr = NULL;
}
Fixed.
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#182 Le 15/04/2010, à 22:55
- grim7reaper
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Oui effectivement, je n'avais pas vu que tu appelais delete_option, mes yeux parcouru sans lire et supposés que c'était un appel à free.
À la limite, fais comme ça
void delete_option_table(struct option*** ptr)
{
int i;
for(i=0;(*ptr)[i]!=NULL;i++)
delete_option(*ptr + i);
free(*ptr);
*ptr = NULL;
}
Dernière modification par grim7reaper (Le 15/04/2010, à 22:56)
Hors ligne
#183 Le 15/04/2010, à 23:03
- grim7reaper
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Bon allez, je vais me mettre en charge.
Petite baisse de régime aujourd'hui, seulement 3 pages (on voit que j'ai pas posté de l'aprem ).
#!/bin/sh
WORLD=`who | cut -d ' ' -f 1 | uniq`
for PEOPLE in $WORLD
do
echo "Good Night $PEOPLE"
done
Hors ligne
#184 Le 15/04/2010, à 23:23
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Oui effectivement, je n'avais pas vu que tu appelais delete_option, mes yeux parcouru sans lire et supposés que c'était un appel à free.
À la limite, fais comme ça
void delete_option_table(struct option*** ptr) { int i; for(i=0;(*ptr)[i]!=NULL;i++) delete_option(*ptr + i); free(*ptr); *ptr = NULL; }
Ce qui va suivre contient des inepties, /me réalise qu’il était fatigué et qu’il aurait dû su coucher au lieu de raconter des conneries.
/me jure que ce n’était pas une vaine tentative d’attendre le Ballmer peak.
Hum… ça ne m’a pas l’air très catholique, tout ça… et si les pointeurs sont représentés par un nombre de byte différent de 1 ? Je sais, je pinaille, mais tu m’as appris à être rigoureux.
On pourrait imaginer ceci :
void delete_option_table(struct option*** ptr)
{
int i;
for(i=0;(*ptr)[i]!=NULL;i++)
delete_option(*ptr + i*(sizeof **ptr);
free(*ptr);
*ptr = NULL;
}
Je crois que ça serait OK. Mais je ne trouve pas ça très propre.
Hé, dis donc, je crois que je me surprends à dire des choses intelligentes…
Sinon, je suis passé par là (bon, il ne faut pas être pris de l’envie de voir la source de la page, sinon ), et quelque chose à attiré mon attention : c’est quoi les opérateurs unaires + et - ?
D’autre part, cela confirme ce que je pensais : il n’y a pas de XOR logique en C.
On peut bien imaginer
(a||b)&&!(a&&b) ou bien (a&&!b)||(!a&&b)
mais bon, je ne trouve pas ça terrible…
BN all
Dernière modification par Pylade (Le 16/04/2010, à 09:11)
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#185 Le 16/04/2010, à 00:16
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
echo plop
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#186 Le 16/04/2010, à 01:00
- helly
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
echo BN
Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.
Hors ligne
#187 Le 16/04/2010, à 01:09
- samυncle
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Hello world
Hors ligne
#188 Le 16/04/2010, à 01:26
- nesthib
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne
#189 Le 16/04/2010, à 03:14
- samυncle
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Hello world
Hors ligne
#190 Le 16/04/2010, à 07:18
- nesthib
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
et sinon ce bot il nous propose un truc ou pas ?
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne
#191 Le 16/04/2010, à 08:28
- grim7reaper
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Hello world !
Hum… ça ne m’a pas l’air très catholique, tout ça… et si les pointeurs sont représentés par un nombre de byte différent de 1 ? Je sais, je pinaille, mais tu m’as appris à être rigoureux.
Et non, ça fonctionne toujours, quelque soit la taille (mais tu a bien fait de le faire remarquer, ta question est légitime)
Cela s'explique pas l'une des choses que je préfère en C (à utiliser sans modération, à condition de ne pas faire de choses trop alambiqués) : c'est de l'arithmétique des pointeurs.
Tu quand tu ajoute un entier à un pointeur, ça augmente l'adresse de entier * sizeof(type pointé) bytes.
Petite démo
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
short *p_si, si;
int *p_i, i;
long *p_li, li;
float *p_f, f;
double *p_d, d;
char *p_c, c;
p_si = &si;
p_i = &i;
p_li = &li;
p_f = &f;
p_d = &d;
p_c = &c;
printf("%p %p\n", (void*)p_si, (void*)(p_si + 1));
printf("%p %p\n", (void*)p_i, (void*)(p_i + 1));
printf("%p %p\n", (void*)p_li, (void*)(p_li + 1));
printf("%p %p\n", (void*)p_f, (void*)(p_f + 1));
printf("%p %p\n", (void*)p_d, (void*)(p_d + 1));
printf("%p %p\n", (void*)p_c, (void*)(p_c + 1));
printf("%p %p\n", (void*)p_si, (void*)(p_si + 42));
printf("%p %p\n", (void*)p_i, (void*)(p_i + 42));
printf("%p %p\n", (void*)p_li, (void*)(p_li + 42));
printf("%p %p\n", (void*)p_f, (void*)(p_f + 42));
printf("%p %p\n", (void*)p_d, (void*)(p_d + 42));
printf("%p %p\n", (void*)p_c, (void*)(p_c + 42));
return EXIT_SUCCESS;
}
Sinon, je suis passé par là (bon, il ne faut pas être pris de l’envie de voir la source de la page, sinon ), et quelque chose à attiré mon attention : c’est quoi les opérateurs unaires + et - ?
Simplement le plus et le moins pour indiqué le signe (int i = -42; int i = +42 (bon là c'est inutile, mais ce n'est pas faux)).
D’autre part, cela confirme ce que je pensais : il n’y a pas de XOR logique en C.
On peut bien imaginer(a||b)&&!(a&&b) ou bien (a&&!b)||(!a&&b)
mais bon, je ne trouve pas ça terrible…
Un XOR logique n'a pas vraiment de signification (quel est le sens if(a XOR b) ?), le XOR est un opérateur de "modification" et le XOR bit à bit (^) rempli très bien sont travail.
Hors ligne
#192 Le 16/04/2010, à 09:35
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Pylade a écrit :Hum… ça ne m’a pas l’air très catholique, tout ça… et si les pointeurs sont représentés par un nombre de byte différent de 1 ? Je sais, je pinaille, mais tu m’as appris à être rigoureux.
Et non, ça fonctionne toujours, quelque soit la taille (mais tu a bien fait de le faire remarquer, ta question est légitime)
Cela s'explique pas l'une des choses que je préfère en C (à utiliser sans modération, à condition de ne pas faire de choses trop alambiqués) : c'est de l'arithmétique des pointeurs.
Tu quand tu ajoute un entier à un pointeur, ça augmente l'adresse de entier * sizeof(type pointé) bytes.
Oui, bien sûr, je ne sais pas à quoi je pensais quand j’ai écrit ça…
D’ailleurs, j’ai édité mon message.
Mais j’ai une vraie question. En utilisant malloc(), est-il garanti que la mémoire allouée sera continue (donc que l’on peut-faire un tableau) ? Si non, est-ce que calloc() le garanti ?
Merci pour ta démo.
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#193 Le 16/04/2010, à 10:05
- Seren
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Oui, bien sûr, je ne sais pas à quoi je pensais quand j’ai écrit ça…
D’ailleurs, j’ai édité mon message.Mais j’ai une vraie question. En utilisant malloc(), est-il garanti que la mémoire allouée sera continue (donc que l’on peut-faire un tableau) ? Si non, est-ce que calloc() le garanti ?
Merci pour ta démo.
Physiquement dans le ou les barettes de RAM, la mémoire allouée n'est pas continue.
Cependant ton processeur ne travaille quasiment jamais avec des adresses physiques, il utilises toujours des adresses virtuelles grâce à un composant qu'on appelle la MMU qui gère des blocs de mémoire de 4kio par défaut (des pages) sous Linux.
En gros la MMU va trouver des blocs de 4kio éparpillés dans la mémoire physique, mais il va créer des tables pour que du point de vue du processeur la mémoire apparaisse comme continu. C'est en hardware hors du proc donc c'est transparent et ça coûte pas de cycles dans le CPU.
CPU <--bus--> MMU <--bus--> RAM
Il y a des méthodes pour allouer de la mémoire physique continue, mais en général c'est fait très tôt au boot de la machine avant que la mémoire ne soit fragmentée. C'est notamment le cas pour l'espace mémoire qui contient le kernel, c'est physiquement et virtuellement continu.
Enfin bref, si tu fais un malloc, et un p++ tu tapperas toujours dans la mémoire allouée (jusqu'à ce que tu dépasses).
Dernière modification par Seren (Le 16/04/2010, à 10:14)
"I am not young enough to know everything". Oscar Wilde
Hors ligne
#194 Le 16/04/2010, à 10:12
- grim7reaper
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Mais j’ai une vraie question. En utilisant malloc(), est-il garanti que la mémoire allouée sera continue (donc que l’on peut-faire un tableau) ? Si non, est-ce que calloc() le garanti ?
Que ce soit malloc ou calloc (de même que realloc), la mémoire est garantie continue (du moins de ton point de vue, physiquement c'est une autre histoire) et alignée.
La différence entre malloc et calloc est que ce dernier initialise la zone allouée à zéro.
Dernière modification par grim7reaper (Le 16/04/2010, à 10:14)
Hors ligne
#195 Le 16/04/2010, à 10:14
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Pylade a écrit :Oui, bien sûr, je ne sais pas à quoi je pensais quand j’ai écrit ça…
D’ailleurs, j’ai édité mon message.Mais j’ai une vraie question. En utilisant malloc(), est-il garanti que la mémoire allouée sera continue (donc que l’on peut-faire un tableau) ? Si non, est-ce que calloc() le garanti ?
Merci pour ta démo.
Physiquement dans le ou les barettes de RAM, la mémoire allouée n'est pas continue.
Ou, bien sûr, d’ailleurs c’est pour ça que la RAM s’appelle comme ça je crois, mais je demandais si on était certain que la mémoire allouée soit logiquement continue.
Pylade a écrit :Mais j’ai une vraie question. En utilisant malloc(), est-il garanti que la mémoire allouée sera continue (donc que l’on peut-faire un tableau) ? Si non, est-ce que calloc() le garanti ?
Que ce soit malloc ou calloc (de même que realloc), la mémoire est garantie continue (du moins de ton point de vue, physiquement c'est une autre histoire) et alignée.
La différence entre malloc et calloc est que ce dernier initialise la zone allouée à zéro.
OK, merci, j’ai ma réponse.
Dernière modification par Pylade (Le 16/04/2010, à 10:16)
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#196 Le 16/04/2010, à 10:19
- Seren
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
Si c'était pas continu, les structures ou tableaux n'aurait pas tellement d'intérêt. Pour passer de tab[0] à tab[1], le CPU serait obligé de faire un calcul bien compliqué .
Dernière modification par Seren (Le 16/04/2010, à 10:23)
"I am not young enough to know everything". Oscar Wilde
Hors ligne
#197 Le 16/04/2010, à 10:35
- Pylades
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
C’est pour ça que je voulais m’assurer qu’il n’y avait pas de risque.
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#198 Le 16/04/2010, à 10:48
- cm-t
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
j'ai peur de dire une bêtise, mais si un tableau n'est rien qu'un pointeur, on s'en fou qu'il soit contigu physiquement non?
Actu Ubuntu ☺/
Pauses Ubuntu sur Paris \_< -t
[(π)] La Quadrature du net
Hors ligne
#199 Le 16/04/2010, à 10:51
- tshirtman
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
d'ou l'intérêt de parcourir les tableaux dans le bon sens
en fait non je dis nimp, c'est a cause des pagefault qu'il faut le faire dans le bon sens.
Dernière modification par tshirtman (Le 16/04/2010, à 10:52)
Hors ligne
#200 Le 16/04/2010, à 10:52
- cm-t
Re : ..:: Topic des Codeurs Couche-Tard [0] ::..
@tshirtman donc tu me confirme que je dis pas une bêtise ? ou alors j'ai mal saisi le débat :S
Actu Ubuntu ☺/
Pauses Ubuntu sur Paris \_< -t
[(π)] La Quadrature du net
Hors ligne