Voila,
tout est dans le titre, je ne parvient pas a comprendre pourquoi j'ai un bug
Merci:)Code:
1
2
3
4
5
6
7
8
9 int i; for(i=0; ((num/=10) != 0); ++i); char *str; str = malloc(sizeof(char) * i); return str;
Version imprimable
Voila,
tout est dans le titre, je ne parvient pas a comprendre pourquoi j'ai un bug
Merci:)Code:
1
2
3
4
5
6
7
8
9 int i; for(i=0; ((num/=10) != 0); ++i); char *str; str = malloc(sizeof(char) * i); return str;
Bonjour,Code:
1
2
3
4
5
6
7
8 int i; for(i=0; ((num/=10) != 0); ++i); char *str; str = malloc(sizeof(char) * i); return str;
merci de compléter un peu, plus un problème est explicite plus il est facile à résoudre et plus la réponse sera claire.
- num cette variable viens d'ou?
- return : semble indiquer que tu es dans une fonction, quel est son prototype
- Si i vaut 0 que retourne malloc(sizeof(char)*i) qui équivaut à malloc(0)?
- quand libère tu la mémoire alloué par malloc?
En effet, je suis dans une fonction. :ccool:
num est un int passé comme argument a la fonction.
et i ne peux pas etre egal a 0.
:aie:
rien ne l'indique dans le bout de code que tu as donné, je ne vois pas ce qui empêche i d'être égal à 0....
Affiche:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <stdio.h> #include <stdlib.h> int main() { int i = 0; int num = 5; printf("num/10=%d\n",num/10); for(i=0;((num/=10) != 0);++i); printf("i=%d\n",i); return EXIT_SUCCESS; }
je te conseille de jeter un oeil ici (notamment la partie sur la division entière):Code:
1
2 num/10=0 i=0
http://c.developpez.com/cours/bernar...gne/node21.php
plus la description du problème est précise plus il est facile à comprendre donc à résoudre car cela évite les fausses piste.
Des deux problèmes suivant lequel est le plus facile à résoudre?
- x = 5 * y - 7 * z, que vaut x.
- x = 5 * y - 7 * z, que vaut x quand y = 2 et z vaut 3.
plusieurs chose peuvent faire planter un malloc,
- tu demande plus que ce que le sytème peu te fournir (souvent une fuite mémoire)
- tu passe un argument invalide
Note aussi que malloc alloue la mémoire mais ne l'initialise pas. c'est à dire que str pointe sur un bloc de mémoire donc le contenu est non définit.
http://rperrot.developpez.com/articles/c/allocationC/
J'ai change comme cela.
Ce que je ne comprend pas c'est que le code compile sans probleme lorsque je met la boucle for en commentaire.Code:
1
2
3
4
5
6 int i=1; for(; ((num/=10) != 0); ++i); char *str; str = malloc(sizeof(char) * i); return str;
le compilateur me dit qu' il manque un ';'quelque part au niveaue de la boucle quand celle ci est active.
Je comprend rien du tout.
Il me dit aussi que str n'est pas declarer.
peux-tu mettre le code réel de la fonction, ainsi que les messages d’erreurs exact du compilateur?
Chez-moi ce code extrapolé avec les informations que tu as fourni compile et s’exécute.
même si je ne le trouve pas super beau.
cf:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <stdio.h> #include <stdlib.h> char * test(int num) { int i=1; for(; ((num/=10) != 0); ++i); char *str; str = malloc(sizeof(char) * i); return str; } int main() { char *p = test(1000); sprintf(p,"abc"); printf("p=%s\n",p); free(p); return EXIT_SUCCESS; }
petite question subsidiaire qui me titille depuis de début, le ';' à la fin du for est-il vraiment intentionnel?Code:
1
2
3
4
5 -*- mode: compilation; default-directory: "d:/dev/" -*- Compilation started at Tue Sep 11 01:04:11 gcc -Wall -Wextra test.c -o test.exe && test.exe p=abc
Tu crois que le garagiste peut la réparer si tu lui dis ça ? :roll:Citation:
Bonjour, ma voiture marche pas, c'est une Twingo.
Ici, c'est pareil. Il faut nous donner un exemple complet minimal, qui reproduit le problème avec le minimum de lignes de codes. Il faut aussi nous dire ce qui ne va pas (en copiant collant les erreurs du compilateur, en disant ce qu'il se passe à l'exécution, à quelle ligne le programme s'arrête....).
On est forts, mais pas totalement devins. La fonction alloue une chaine suffisamment longue pour écrire tous les chiffres d'un nombre en texte ?
Sauf erreur de ma part, c'est complétement normal que cela ne marche pas.
Tu essayes d'allouer la même variable déjà allouée.
Je te rappelle que tu es dans une boucle. Soit tu alloues un tableau de pointeur et dans ce cas là ce que tu fais pourrait être juste, soit il faut que tu utilises realloc pour reallouer ton pointeur. :nono:
D'ailleurs, il manque le cast devant le malloc : (char*)malloc.
Compiles ton code sous linux, tu vas comprendre.
Au passage, la façon dont tu écries ta boucle est selon moi vraiment :aie:. Un while me parait plus clair et approprié.
Aussi, diviser 1000 par 10 tant que la division est non nulle, autant faire un while(1) puisque ce sera toujours vrai :alerte:. Si tu veux blinder ta RAM, enjoy :zekill::twisted::massacre:
Cordialement.
@darkwall_37 : c'est n'importe quoi. L'allocation n'est pas dans une boucle, il n'y a pas besoin de cast devant malloc, et la condition de sa boucle for n'est pas toujours vraie.
@IsraGab : qu'est-ce qui te fait dire que ton allocation dynamique ne marche pas ? Il me semble qu'elle marche, que ton problème est ailleurs mais que tu ne nous donne pas assez d'information pour le trouver.
+1 pour gulain : tu dis vraiment n'importe quoi darkwall quant à la boucle, désolé. Le malloc n'est fait qu'une fois car il y a un point virgule avec le for. On ne fait pas une simple division mais une division et une affectation donc num change. Un for est très adapté à la situation. Tu peux faire plusieurs malloc() du même pointeur, mais pas de free() *.
Le code suivant compile très bien et fonctionne très bien :
i indique le nombre de chiffre dans le nombre num et alloue un pointeur de cette taille. Pas de chance si c'est pour faire une conversion int --> string, il manque une case pour '\0'. De plus, il existe la fonctionne snprintf() pour faire un tel calcul.Code:
1
2
3
4
5
6
7 int i=1, num = 1; for(; ((num/=10) != 0); ++i); char *str; str = malloc(sizeof(char) * (size_t) i); printf("%d , @%p", i, str);
* : pour l'exemple :
Ca compile, ça fonctionne. Il a une fuite mémoire puisque l'espace précédemment alloué n'est pas libéré avec une nouvelle affectation. Si malloc plantait en affectant un pointeur non NULL, les fuites mémoires se transformeraient en crash des programmes.Code:
1
2
3
4
5
6
7
8
9 int main(void) char * p; int i = 10; while(i--) { p = malloc(10); } return 0; }
PS : j'ai une Twingo.
Arf j'ai pas vu le ';'
Je croyais que le for était équivalent à
while ( num != 0 )
{
num=num/10;
}
Il l'est, à l'incrémentation de i près (rajouter i+=1 dans la boucle ne suffit pas, il faut aussi modifier l'initialisation de i).
Oui (i ne n'intervient pas dans la condition de sortie de la boucle donc je l'ai pas mis) et donc 1000 divisé n fois par 10 ne fera jamais 0.
Et aucun nombre divisé par n'importe quel nombre soit t'il sera égal 0. Donc la condition de sortie de la boucle est mauvaise non ?
1000/10 = 100
100/10 = 10
10/10 = 1
Et en C, 1/10 = 0.
Il suffit d'exécuter l'instruction suivante pour s'en convaincre : printf("%d vs %f vs %f", 1/10, 1.0/10, 1/10.0);.
CQFD. ;)
Okay autant pour moi. J'ai pas pensé au cast int.
Il n'y a pas de cast dans :
int x = 1/10;.
float x = 1/10; //x vaut 0.
Un int divisé par un int donne un int.
*ressort son cours*Là on est de l'int avec le l'int, donc pas de conversions.Code:
1
2
3
4
5
6 - promotion entière des petites valeurs (ex : char -> int) - examen des opérateurs et des types des opérandes -> si types identiques, on fait le calcul -> sinon une conversion se produit -> vers le type le plus grand, en flottant si besoin est (ex char + double, conversion du char en double). -> conversion vers unsigned (resp. long) si un des opérandes est unsigned (resp. long).
Si tu veux le nombre de chiffres dans ton nombre, le problème ici est la nécessité d'arrondir ta division au supérieur:
Ensuite, il faut un cas spécial pour quand num valait zéro, parce que la représentation de zéro est "0" plutôt qu'une chaîne vide:Code:
1
2 int i; for(i=0 ; ((num+9)/10) != 0 ; ++i, num/=10) {}
Et ensuite, vu que c'est pour un malloc de chaîne de caractères, il faut rajouter la place pour le caractère nul:Code:if(i==0) i=1;
Code:
1
2 char *str; str = malloc(sizeof(char) * (i+1));
Edit: L'autre façon, plus simple, c'est tester la nullité avant de diviser par 10:
Code:
1
2
3
4
5 int i; char *str; for(i=0 ; num != 0 ; ++i, num/=10) {} if(i==0) i=1; str = malloc(sizeof(char) * (i+1));
Ceci dit, si le but est de mettre un entier dans un chaine C, cas ou l'on peut avoir besoin de connaitre le nombre de digit et allouer un chaine.
Autant allouer directement le nombre max de digit d'un entier (ça évite la boucle)
Code:
1
2
3
4
5
6
7 char * numToStr(int32_t num) { // -2147483648 // 2147483647 char * s = malloc(sizeof(char)*12); sprintf(s,"%d",num); }