Bonjour !
Aujourd'hui, j'ai un problème de malloc.
Donc j'ai une fonction qui récupère des chaines de caractères pour se connecter a une BD. L'ensemble se passe plutot bien, sauf quand les chaines de carctères font une certaine longueur (?)
Voici le code incriminé :
Les lignes :
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 int Query_update_settings(PGconn * conn, const char ** paramValues) { PGresult * res; int len_str; char * query; fprintf(stderr,"%s %s %d\n", paramValues[1], paramValues[0], strlen(paramValues[1])); /* imprime : "nb_max_users 0 12" */ len_str = strlen(paramValues[1]); fprintf(stderr,"avant malloc param : %s\n", paramValues[1]); /* imprime : "avant malloc param : nb_max_users" */ malloc(len_str+3); fprintf(stderr,"apres malloc param : %s\n", paramValues[1]); /* imprime : "apres malloc param : nb_max_users^Y" */ if ((query = malloc(strlen(paramValues[1]) + strlen(paramValues[0]) + 50)) != NULL) { fprintf(stderr,"%s %s %d\n", paramValues[1], paramValues[0], strlen(paramValues[1])); strcpy(query,"UPDATE settings SET value = '"); strcat(query,paramValues[0]); strcat(query,"' WHERE name = '"); strcat(query,paramValues[1]); fprintf(stderr,"%s %d\n", paramValues[1], strlen(paramValues[1])); strcat(query,"'"); fprintf(stderr,"query : %s \n", query); }
ne servent absolument a rien, c'était juste pour vérifier que le problème vient bien du malloc.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 fprintf(stderr,"%s %s %d\n", paramValues[1], paramValues[0], strlen(paramValues[1])); /* imprime : "nb_max_users 0 12" */ len_str = strlen(paramValues[1]); fprintf(stderr,"avant malloc param : %s\n", paramValues[1]); /* imprime : "avant malloc param : nb_max_users" */ malloc(len_str+3); fprintf(stderr,"apres malloc param : %s\n", paramValues[1]); /* imprime : "apres malloc param : nb_max_users^Y" */
Donc, sans ces lignes, j'ai juste if (query = malloc(strlen ...)), ce qui fonctionne bien, sauf quand les chaines contenues dans paramValues[1] font 12 ou 13 ou 28 ou 29 ou 60 ou 61 (je n'ai pas cherché plus loin), auquel cas j'ai un caractère en trop ou modifié (le caractère 13 est ajouté, ou modifié par exemple). Lorsque la chaine fait 5 caractères, ou 10, j'obtiens bien le bon résultat ....
Voila, en fait je ne sais même pas où cherché ? Est-ce que je n'ai rien compris a malloc, ou est-ce un bug du compilateur, de la librairie, d'autre chose ? Un comportement normal ?
Une théorie (pondue par ma copine ! :-) ) :
Lorsque malloc est utilisé avec une certaine longueur de chaine, soit il ajoute un caractere aleatoire a la fin soit il remplace le dernier. Après une petite analyse, voici ma théorie :
si on transforme la longueur de la chaine en binaire, le probleme intervient lorsque les 2 et 3eme bits de poids faibles sont à 1 et le premier à 0.
Explication :
chaine de longueur 11 -> 1011 => tout va bien
chaine de longueur 12 -> 1100 => malloc rajoute un caractère
chaine de longueur 13 -> 1101 => malloc remplace le dernier caractère
chaine de longueur 14 -> 1110 => tout va bien
Si on rajoute un bit, on a la meme chose :
chaine de longueur 28 -> 11100 => malloc rajoute un caractère
chaine de longueur 29 -> 11101 => malloc remplace le dernier caractère
chaine de longueur 60 -> 111100 => malloc rajoute un caractère
chaine de longueur 61 -> 111101 => malloc remplace le dernier caractère
Par contre, pour des chaines de longueurs 27,30,59, ou 62, ma chaine ne bouge pas.
Y-a-t-il une utilisation particulière de la mémoire qui pourrait provoquer ce genre de truc ?
Merci !
Jeremy
Partager