Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
668 connectés 

 

 

 Mot :   Pseudo :  
 
 Page :   1  2  3  4  5  6
Page Suivante
Auteur Sujet :

[C/C++] Défi: Trouvez les bogues ! (n°42)

n°266247
Kristoph
Posté le 10-12-2002 à 09:39:53  profilanswer
 

Reprise du message précédent :
Si le but est de mimer le comportement de realloc, il faut aussi penser a faire un simple malloc dans le cas ou buf vaut NULL ( donc pas alloué avant l'appel )
Et si nc vaut 0; il faut faire un free sur buf

mood
Publicité
Posté le 10-12-2002 à 09:39:53  profilanswer
 

n°266307
Taz@PPC
saloperie de i=`expr $i + 1`;
Posté le 10-12-2002 à 12:00:02  profilanswer
 

oui!


---------------
du bon usage de rand [C] / [C++]
n°266862
Musaran
Cerveaulté
Posté le 11-12-2002 à 02:23:54  profilanswer
 

Kristoph a écrit :

[nom]Taz@PPC a écrit[/nom]on ferait bien de retourner temp.

5, dispendieux) Bien sûr, la double copie/allocation est tout simplement inutile.
 

Citation :

+ y a 2 l a Reallocate

6, pinaillage) Mais oui, la mauvaise orthogrape est un moyen sournois de nuire à l'utilisateur.
 

Citation :

+ le memset(0) peut avoir un effet désastreux avec des types autre qu'entiers

Certes certes, mais cela sort du cadre de cette fonction. C'est pas le joli new du C++.
 

Kristoph a écrit :

Si le but est de mimer le comportement de realloc, il faut aussi penser a faire un simple malloc dans le cas ou buf vaut NULL ( donc pas alloué avant l'appel )
Et si nc vaut 0; il faut faire un free sur buf


Je n'avais pas non plus pensé à ça.
7, pinaillage) Le cas ns=0 devrait être géré spécifiquement, mais bizarrement buff=NULL et os=0 sont gérés spontanément. Aucun doute que ce n'était pas intentionnel.
Pinaillage, car cet aspect de la fonction realloc ne devrait même pas exister, et qu'il vaut mieux ne pas l'imiter.
 
 
Allez:
8, pinaillage) ns et os veulent dire 'new size' et 'old size'. En bon habitués vous l'aviez bien sûr deviné, mais il faut des noms plus explicites.
 
9, dispendieux) Le memset 0 est inutile dans la version originale, puisqu'on écrase immédiatement avec autant de données.
(considéré séparément des autres bogues)
 
Wééééh ! Encore un compteur de pété !
 
 
Il ne reste plus qu'à mieux préciser le bogue 31.


Message édité par Musaran le 11-12-2002 à 02:24:41

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°266876
Taz@PPC
saloperie de i=`expr $i + 1`;
Posté le 11-12-2002 à 08:38:27  profilanswer
 

le memset n'est pas forcément inutile, si on veut avoir l'assurance  que tout est propre.... d'ou calloc qui fait bien mieux le boulot (en mmappant sur /dev/zero si besoin est)


---------------
du bon usage de rand [C] / [C++]
n°266897
einstein2
Windaube, FAIS l'EFFORT !
Posté le 11-12-2002 à 09:38:06  profilanswer
 

Code :
  1. (void*) Realocate(void* buf, int os, int ns){
  2.       void* temp; // correct
  3.       // ben 2 cas ns >= os ou ns < os
  4.       temp = malloc(os);
  5.       memcpy(temp, buf, os);// suppose que taille buf est os au min  
  6.       free(buf);//ok
  7.       buf = malloc(ns);//ok
  8.       memset(buf, 0, ns);//ok utilité?
  9.       memcpy(buf, temp, min(os, ns));// on alloue le min
  10.       free(temp);
  11.       return buf;
  12. }


Message édité par einstein2 le 11-12-2002 à 12:13:22
n°267746
Musaran
Cerveaulté
Posté le 12-12-2002 à 02:35:08  profilanswer
 

einstein2 a écrit a écrit :

(void*) Realocate...


Je sais pas pourquoi tu mets des parenthèses, mais ça compile pas !
 

Citation :

memcpy(temp, buf, os)// suppose que taille buf est os au min  

Il est censé être ==os par définition.
Et de toute façon on peut pas vérifier
 

Citation :

memcpy(buf, temp, min(os, ns))// on alloue le min

Clap clap, le bogue 31 est complet maintenant !
(sauf que c'est pas une allocation mais une copie)
 
Ce code viens de :
http://www.mindprod.com/unmain.html How To Write Unmaintainable Code
 
Pour le sport, ceci suffisait pour remplacer realloc:
(en ignorant les cas revenant à free ou malloc)

Code :
  1. #include <stdlib.h>
  2. #define min(a,b) ((a)>(b) ? (b) : (a))
  3. void* Reallocate(void* oldbuffer, size_t oldsize, size_t newsize){
  4. void* newbuffer = malloc(newsize);
  5. if(newbuffer != NULL)
  6.  memcpy(newbuffer, oldbuffer, min(oldsize, newsize));
  7. free(oldbuffer);
  8. return newbuffer;
  9. }


Message édité par Musaran le 12-12-2002 à 02:35:31

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°267747
Musaran
Cerveaulté
Posté le 12-12-2002 à 02:35:59  profilanswer
 

Bon, ben on continue...
[B]Trouvez les 8 bogues ![/B]

Code :
  1. class tampon{
  2. char* data;
  3. int taille;
  4. tampon(int taille_):taille(taille_),data(malloc(taille)){}
  5. ~tampon(){delete data}
  6. }


 
J'ai fait bien exprès d'en mettre plein de gros évidents pour cacher les perfides.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°267766
Kristoph
Posté le 12-12-2002 à 09:42:52  profilanswer
 

Edit : c'est faux ça : - Pas d'appel de fonctions dans les paramètres de constructeurs : ie pas de data(malloc(taille))
 
- Il faut absolument faire un cast du paramètre de retour du malloc en C++
 
Edit : c'est pas vraiment interdit mais quand même : - Pas de malloc en C++ ! Utilise new []. Retire ça, utilises string :D
 
- Plus perfide, si on autorise le malloc ( ou si je me suis gourré ;) ), ça ne marche pas quand même car taille est "construit" après data. En effet l'ordre de construction n'est pas celui dans lequel tu l'écris ( ici : taille(taille_), data(malloc(taille)) ), mais l'ordre dans lequel les données membres sont définies dans la classe. Donc data d'abord, puis taille.
 
- Pas de delete de données alloués par malloc.
 
- Si le char * avait été alloué comme il faut, il faudrait faire un delete [] pour le new [] mis à la place du malloc
 
- Problème classique du constructeur par recopie/opérateur de  
recopie implicite qui va créer de multiples references à data et donc va finir par faire de multiples desalloccations de data.
 
- Le seul contructeur normal de tampon est private, ça n'aide pas. D'ailleurs tous les membres de tampon sont private !
 
- Oubli d'un ; à la fin de la déclaration de tampon
 
- Oubli d'un ; à la fin du code du destructeur ( après le delete ).
 
Edit : on enleve les 2 fautes et ça fait 8.


Message édité par Kristoph le 12-12-2002 à 11:08:06
n°267788
BifaceMcLe​OD
The HighGlandeur
Posté le 12-12-2002 à 10:42:20  profilanswer
 

Ca fait plus que huit, ça...  :heink:  :D

n°267811
Kristoph
Posté le 12-12-2002 à 11:06:07  profilanswer
 

Normal, je ratisse large. Et puis en y repensant, je pense que le malloc est autorisé, mais qu'il n'est simplement pas casté correctement. Et les oubli de ; son vraiment anodins ;)
 
Et puis, je fais un peu de doctrine au milieu ( le malloc à remplacer par un new par ex )


Message édité par Kristoph le 12-12-2002 à 11:06:44
mood
Publicité
Posté le 12-12-2002 à 11:06:07  profilanswer
 

n°268114
blackgodde​ss
vive le troll !
Posté le 12-12-2002 à 14:39:52  profilanswer
 

pour les bogues 31-32, il faut aussi regarder si OldBuff != NULL et est bien alloué sinon boom au 1er memcpy


---------------
-( BlackGoddess )-
n°268800
Musaran
Cerveaulté
Posté le 13-12-2002 à 04:53:22  profilanswer
 

1/34)

Citation :

- Il faut absolument faire un cast du paramètre de retour du malloc en C++

Et oui, c'est en C que c'est optionnel.
A noter qu'il est possiblement envisagé que le C++ accepte le comportement C (void* convertible en any*), au nom de l'inter-compatibilité.
 

Citation :

Utilise new []. Retire ça, utilises string

Mais non ! Sinon, comment je fais des bogues moi ?
 
2/35)

Citation :

- Plus perfide, si on autorise le malloc ( ou si je me suis gourré   ), ça ne marche pas quand même car taille est "construit" après data. En effet l'ordre de construction n'est pas celui dans lequel tu l'écris ( ici : taille(taille_), data(malloc(taille)) ), mais l'ordre dans lequel les données membres sont définies dans la classe. Donc data d'abord, puis taille.

Le pot aux roses est découvert !
L'explication me vient du livre "Le C++ efficace" de Scott Meyers:
-Le destructeur doit détruire les objets membres dans l'ordre inverse de leur construction, c'est nécessaire pour le déroulage de pile de la gestion d'exception.
-Il peut y avoir plusieurs constructeurs, chacun mentionnant l'initialisation de ces objets dans divers ordres.
-Plutôt que de devoir ajouter des structures cachées pour mémoriser l'ordre, il a été choisi de suivre un ordre forcément unique: celui de la déclaration des membres.
 
3/36)

Citation :

- Pas de delete de données alloués par malloc.
- Si le char * avait été alloué comme il faut, il faudrait faire un delete [] pour le new [] mis à la place du malloc37)

C'est un seul bogue: l'allocation et la libération ne correspondent pas.
 
4/37)

Citation :

- Problème classique du constructeur par recopie/opérateur de recopie implicite qui va créer de multiples references à data et donc va finir par faire de multiples desalloccations de data.

Tu as trouvé bien facilement... t'aurais pas déjà fait cette bêtise plusieurs fois ?
 
Première solution, les interdire:

Code :
  1. class tampon{
  2. //...
  3. private:
  4. tampon& operator=(const tampon& rhs); //opérateur d'affectation
  5. tampon(const tampon&); //constructeur de recopie
  6. };


Deuxième solution, les gérer:

Code :
  1. class tampon{
  2. //...
  3. public:
  4. tampon& operator=(const tampon& rhs){
  5.  if(this!=&rhs){ //vérifier qu'on ne se copie pas soi-même
  6.   //gérer le redimmensionnement et la copie
  7.  }
  8.  return *this;
  9. }
  10. tampon(const tampon&){
  11.  //gérer l'allocation et la copie
  12. }
  13. };

Avec le destructeur et le constructeur, c'est la forme de Coplien: ce que doivent avoir des classes qui s'allouent des ressources.
 
5/38)

Code :
  1. - Le seul contructeur normal de tampon est private, ça n'aide pas. D'ailleurs tous les membres de tampon sont private !

C'est bête, mais il m'arrive encore d'oublier de placer public: !
Le destructeur doit être publique aussi.
 
6/39)

Citation :

- Oubli d'un ; à la fin de la déclaration de tampon

Oui. Mais au fait, pourquoi il en faut un ?
La définition d'une classe est elle-même utilisable comme une mention de type, et peut servir à créer des objets directement:

Code :
  1. //ceci...
  2. class A{};
  3. A a;
  4. //..peut être regroupé
  5. class A{} a;

Donc, si on ne met pas le ";", ce qui vient après est interprété comme un nom de variable.
 
On constate aussi qu'avec "class A{};" ,en plus de définir un type, on mentionne ce type seul sans variable.
Puisque le C++ déteste faire des cas particuliers, on en déduit que c'est aussi valable avec les types intégrés:

Code :
  1. int; //légal

Voilà, c'était le truc inutile du jour (vérifié dans les spécifications du langage).
 
7/40)

Citation :

- Oubli d'un ; à la fin du code du destructeur ( après le delete ).

Code :
  1. {delete data}

Et pourquoi a-t'on tendance à l'oublier celui-là ?
Tout naturellement parce que l'accolade fermante ferme la marche et semble donc naturellement mettre fin à l'instruction.
Le C&C++ ne montrent d'ailleur pas le bon exemple avec for:

Code :
  1. for(i=0 ; i<l ; ++i)

La troisième instruction est terminée par ) et non pas ";".
C'est une entorse à la règle qui prévaut ailleurs que ";" est un terminateur et qu'il est obligatoire.
Au lieu de ça, dans le for, le ";" sert de séparateur et ne se trouve qu'entre deux instructions.
Voilà, c'était le petit défaut du C&C++ du jour.
 
 
Et donc, il reste un bogue/défaut à trouver.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°268801
Musaran
Cerveaulté
Posté le 13-12-2002 à 04:54:24  profilanswer
 

blackgoddess a écrit :

pour les bogues 31-32, il faut aussi regarder si OldBuff != NULL et est bien alloué sinon boom au 1er memcpy

Les paramètre sont censés être valides. On ne réalloue pas le néant.
On pourrait le tester dans un assert, mais ça sort du cadre du défi.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°268813
blackgodde​ss
vive le troll !
Posté le 13-12-2002 à 08:48:58  profilanswer
 

Code :
  1. for(i=0 ; i<l ; ++i)


 
et si on veut lettre plusieurs instructions pour i=0 ou pour ++i, c'est possible ? comment on fait ?


---------------
-( BlackGoddess )-
n°268829
Kristoph
Posté le 13-12-2002 à 09:33:47  profilanswer
 

Musaran a écrit :

Le pot aux roses est découvert !
L'explication me vient du livre "Le C++ efficace" de Scott Meyers:


 
Je vois qu'on a les même références :D
 
blackgoddess : Utilise l'opérateur , qui existe déja en C

n°268912
blackgodde​ss
vive le troll !
Posté le 13-12-2002 à 11:39:56  profilanswer
 

ok d'accord, mci :)


---------------
-( BlackGoddess )-
n°269530
Musaran
Cerveaulté
Posté le 14-12-2002 à 02:50:15  profilanswer
 

Ce qu'on ne peut pas faire:

Code :
  1. for(int a=0, short b=1 ; //combiner deux déclarations de type différentes
  2. for({a=0;b=1;} ; //inclure un bloc
  3. for(int a=0, b=1 ; //combiner déclaration+expression séparée...


Ce qu'on peut faire:

Code :
  1. for(int a=(b=1,0); //...à moins d'être pervers!
  2. for(int a=0, b=1 ; //combiner deux déclarations de type identique
  3. for(a=0,b=1 ; //combiner deux instructions


D'autres idées ?
 
 
8/41) Dernier bogue (plutôt un défaut)
taille est d'un type qui peut être négatif.
Il devrait être tout simplement du type attendu par malloc: size_t.
 
La différence avec le cas NULL précédent, c'est qu'on ne peut empêcher l'utilisateur de transmettre NULL, alors qu'ici on peut empêcher complètement les nombres négatifs.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°269557
Kristoph
Posté le 14-12-2002 à 10:48:08  profilanswer
 

Tu peux m'expliquer la difference entre ces 2 cas dont l'un est possible et l'autre non ?
 

Code :
  1. for(int a=0, b=1 ; //combiner déclaration+expression séparée...
  2. for(int a=0, b=1 ; //combiner deux déclarations de type identique


 
Merci d'avance :D

n°269829
blackgodde​ss
vive le troll !
Posté le 14-12-2002 à 22:52:20  profilanswer
 

c moi qui c pas lire ou tu as écrit 2 fois la mm chose ?!?


---------------
-( BlackGoddess )-
n°269871
Kristoph
Posté le 15-12-2002 à 01:14:13  profilanswer
 

J'ai juste fais du copier coller ;)

n°269872
blackgodde​ss
vive le troll !
Posté le 15-12-2002 à 01:16:39  profilanswer
 

ah !! oui !! si g bien compris ds le 1er cas du déclare a et tu le met egal a 1, et tu mets juste b egal 1, alors que ds le 2eme cas tu déclare a et b et tu mets a egal 0 et b egal 1 ... g bien compris ?


---------------
-( BlackGoddess )-
n°269897
Musaran
Cerveaulté
Posté le 15-12-2002 à 04:15:13  profilanswer
 

La différence ?
Dans le premier l'intention est "b=1" et on obtient "int b=1". D'où le "int a=(b=1,0);" suivant.
Dans le second, c'est bien "int b=1" qu'on veut.
Donc, BlackGoddess: Oui au niveau de l'intention.
 
La syntaxe du for est un peu cafouilleuse...
Mais qu'aurait-on pu utiliser comme séparateur ?
":" ne fait pas l'affaire non plus.
"," non plus
"}{" non plus


Message édité par Musaran le 15-12-2002 à 04:16:28

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°276992
leneuf22
Posté le 28-12-2002 à 20:51:04  profilanswer
 

Tiens, voilà un bug que j'ai trouvé très interressant :
Il est très simple à résoudre, mais le but est de comprendre :)
 
À conseiller à tous ceux qui confondent nom de tableau et pointeur !
 
BUG n° 42
 

Code :
  1. /*----fichier1.c----*/
  2. int tab[3];
  3. int main(void) {
  4.     void f(void);
  5.     tab[0] = -1;
  6.     f();
  7.     return 0;
  8. }
  9. /*----fichier2.c----*/
  10. extern int* tab;
  11. void f(void) {
  12.     int x;
  13.     x = *tab;
  14. }


 
 
Mais... que se passe-t-il ?


Message édité par leneuf22 le 28-12-2002 à 20:53:26
n°278413
vorpal66
Posté le 02-01-2003 à 15:56:38  profilanswer
 

Up !
 
 :bounce:  
 
 
Tres tres interessant comme comportement !
Essayez de changer le type apres l'extern, tout passe !
(Solaris 8, Compilo Sun de base)
extern double ***tab ou exterm char **************tab,
rien ne le gene !   :??:

n°278721
leneuf22
Posté le 03-01-2003 à 13:22:49  profilanswer
 

Je ne suis pas sur de comprendre ce que tu dis...
 
C'est normal que tout passe, vu que le compilateur compile les fichiers séparément.
L'erreur n'est pas à la compilation, mais à l'exécution !

n°278755
vorpal66
Posté le 03-01-2003 à 14:14:20  profilanswer
 


Les fichiers sont compiles separement bien sur mais donnent
1 seul binaire a la fin. Et au link, ca me gene qd meme un peu
que le compilo lie le int tab[3] du fichier 1
avec un double *******tab du fichier2 en pensant que c'est
la meme variable. C'est ca que je voulais dire  :pt1cable:

n°279049
Musaran
Cerveaulté
Posté le 04-01-2003 à 04:39:49  profilanswer
 

Le C++ décore les noms selon leur type (genre tab@I3), ce qui donnerait une erreur de liaison (le C++ c'est bien :sol: ).
Le C ne le fait pas et n'y vois que du feu.
 
C'est pour éviter ce genre de clownerie qu'il faut partager les déclarations par un header inclus, et l'inclure même/surtout dans le fichier qui les définit:

Code :
  1. /*----fichier1.h----*/
  2. extern int tab[3];
  3. /*----fichier1.c----*/
  4. #include "fichier1.h" //auto-vérification de cohérence
  5. int tab[3];
  6. //...
  7. /*----fichier2.c----*/
  8. #include "fichier1.h"
  9. //...


Message édité par Musaran le 04-01-2003 à 04:40:18

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°279269
leneuf22
Posté le 04-01-2003 à 17:46:56  profilanswer
 

Oui, bien sur, mais la question est : pourquoi est-ce que ça ne marche pas ? :)
 
Je parle de mon exemple, bien entendu, pas du double******** !


Message édité par leneuf22 le 04-01-2003 à 17:48:59
n°279498
Musaran
Cerveaulté
Posté le 05-01-2003 à 06:31:07  profilanswer
 

Code :
  1. *tab;

Si 'tab' est un tableau: Prendre son adresse (adresse de son premier élément), déréférencer.
Si 'tab' est un pointeur: Prendre son contenu, déréférencer.
 
Donc ton exemple lit les premières données d'un tableau d'int comme un pointeur. Un pointeur fou !
 
Cette différence de traitement adresse de/contenu de m'a permis de faire cette macro:

Code :
  1. //Teste si l'argument est un tableau (pas un pointeur ou adresse)
  2. //tableau : retourne 1/true (les chaînes littérales en sont)
  3. //pointeur: retourne 0/false
  4. //littéral: error '&' on constant
  5. //autre   : error subscript requires array or pointer type
  6. #define ISARRAY(a) ( (void*)&(a)==(void*)&(a)[0] )


A noter que cette comparaison d'adresses ne faisant pas partie du même objet n'est pas autorisée par le standard.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°377287
Taz
bisounours-codeur
Posté le 29-04-2003 à 23:28:29  profilanswer
 

reviens musaran!!!!

n°377478
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-04-2003 à 09:04:41  profilanswer
 

:sweat:


---------------
J'ai un string dans l'array (Paris Hilton)
n°377740
LeGreg
Posté le 30-04-2003 à 11:05:31  profilanswer
 

que pasa ?
 
LeGreg

n°457391
Taz
bisounours-codeur
Posté le 14-07-2003 à 18:01:58  profilanswer
 

bon, je remonte ce topic, l'été va être long et je pense que j'aurais pas grand chose à me mettre sous la dent... j'essaierais de réfléchir à un ou deux bugs

n°457417
nraynaud
lol
Posté le 14-07-2003 à 18:12:41  profilanswer
 

++Taz a écrit :

bon, je remonte ce topic, l'été va être long et je pense que j'aurais pas grand chose à me mettre sous la dent... j'essaierais de réfléchir à un ou deux bugs

On est obligé de les faire en C++ ? On peu pas déplacer le topic dans divers et ouvrir le débat ?


---------------
trainoo.com, c'est fini
n°457425
Taz
bisounours-codeur
Posté le 14-07-2003 à 18:17:09  profilanswer
 

:D c'est vrai que à la base ce topic était plutot bugs en C

n°457432
nraynaud
lol
Posté le 14-07-2003 à 18:25:53  profilanswer
 

++Taz a écrit :

:D c'est vrai que à la base ce topic était plutot bugs en C

bon allez, gentil caml d'un pote :

Citation :

Ou comment bien se prendre le chou pour calculer la longueur d'un
tableau connaissant ses limites dans un style Haskélien...
 
let ( <*> ) f g x = f (g x) (* Composition de fonctions *)
let flip f x y = f y x (* Inversion des arguments *)
let uncurry f (x, y) = f x y (* Décurryfication d'une fonction *)
 
let bounds a = 0, Array.length a - 1
(* Un tableau commence toujours à 0 en OCaml *)
 
Et enfin, la formule magique :
 
let length a = ((( + ) 1) <*> (uncurry (flip ( - ))) <*> bounds) a
 
Car, comme chacun sait, la longueur d'un tableau c'est m - n + 1 où n et m sont les indices extrêmes dans l'ordre.


la question :

Citation :


    Pourquoi n'écrit-on pas "uncurry <*> (flip ( - ))" à la place de "uncurry (flip ( - ))" ?


 
edit : la réponse est sur mon blog pour les glandeurs


Message édité par nraynaud le 14-07-2003 à 18:26:55

---------------
trainoo.com, c'est fini
n°457437
Taz
bisounours-codeur
Posté le 14-07-2003 à 18:29:58  profilanswer
 

mince  :pt1cable:
 
/usr/bin/ld:dawa: file format not recognized; treating as linker script
/usr/bin/ld:dawa:1: syntax error
collect2: ld a retourné 1 code d'état d'exécution
 
c'est du chinois pour moi ton truc

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3  4  5  6
Page Suivante

Aller à :
Ajouter une réponse
 

Sujets relatifs
comment trouvez mon site???[JS] JEU: Trouvez l'erreur :o)
Un petit défi : echecs et IA[DEFI DELPHI] - Delayer un buffer pour les Visualization Winamp
Defi programmation JAVA ou autreDefi PHP n°3 !!!
Plus de sujets relatifs à : [C/C++] Défi: Trouvez les bogues ! (n°42)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR