Alors je ne sais pas ce que tu utilises comme compilo mais :
$ gcc -Wall -Wextra -c ps.c
ps.c: In function ‘newBalise’:
ps.c:59:43: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
59 | strncpy(nbalise->name, name_b, sizeof name_b);
| ^~~~~~
même avec clang
$ clang -Wall -Wextra -c ps.c
ps.c:59:43: warning: 'strncpy' call operates on objects of type 'char' while the size is based on a different type 'char *' [-Wsizeof-pointer-memaccess]
strncpy(nbalise->name, name_b, sizeof name_b);
~~~~~~ ^~~~~~
ps.c:59:43: note: did you mean to provide an explicit length?
strncpy(nbalise->name, name_b, sizeof name_b);
^~~~~~
après si tu as une version récente de gcc tu peux carrément :
$ gcc -g -fanalyzer -Wall -Wextra -o ps ps.c
ps.c: In function ‘newBalise’:
ps.c:59:43: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
59 | strncpy(nbalise->name, name_b, sizeof name_b);
| ^~~~~~
ps.c: In function ‘main’:
ps.c:84:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
84 | int main(int argc, char const *argv[])
| ~~~~^~~~
ps.c:84:32: warning: unused parameter ‘argv’ [-Wunused-parameter]
84 | int main(int argc, char const *argv[])
| ~~~~~~~~~~~~^~~~~~
ps.c: In function ‘init_HTML’:
ps.c:30:21: warning: dereference of possibly-NULL ‘balise’ [CWE-690] [-Wanalyzer-possible-null-dereference]
30 | balise->numTabs = 0;
| ~~~~~~~~~~~~~~~~^~~
‘init_HTML’: events 1-2
|
| 29 | Balise *balise = malloc(sizeof(Balise));
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) this call could return NULL
| 30 | balise->numTabs = 0;
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (2) ‘balise’ could be NULL: unchecked value from (1)
|
ps.c:36:13: warning: dereference of possibly-NULL ‘html’ [CWE-690] [-Wanalyzer-possible-null-dereference]
36 | html->f = NULL;
| ^
‘init_HTML’: event 1
|
| 28 | HTML *html = malloc(sizeof(HTML));
| | ^~~~~~~~~~~~~~~~~~~~
| | |
| | (1) this call could return NULL
|
‘init_HTML’: event 2
|
| 36 | html->f = NULL;
| | ^
| | |
| | (2) ‘html’ could be NULL: unchecked value from (1)
|
ps.c:44:12: warning: leak of ‘balise’ [CWE-401] [-Wanalyzer-malloc-leak]
44 | return html;
| ^~~~
‘init_HTML’: events 1-5
|
| 29 | Balise *balise = malloc(sizeof(Balise));
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
| 30 | balise->numTabs = 0;
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (2) assuming ‘balise’ is non-NULL
|......
| 40 | if((! html->f) || html == NULL || balise == NULL){
| | ~
| | |
| | (3) following ‘false’ branch...
|......
| 44 | return html;
| | ~~~~
| | |
| | (4) ...to here
| | (5) ‘balise’ leaks here; was allocated at (1)
|
ps.c: In function ‘newBalise’:
ps.c:57:22: warning: dereference of possibly-NULL ‘nbalise’ [CWE-690] [-Wanalyzer-possible-null-dereference]
57 | nbalise->suivant = NULL;
| ^
‘newBalise’: event 1
|
| 55 | Balise* nbalise = malloc(sizeof(Balise));
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) this call could return NULL
|
‘newBalise’: event 2
|
| 57 | nbalise->suivant = NULL;
| | ^
| | |
| | (2) ‘nbalise’ could be NULL: unchecked value from (1)
|
ps.c:69:1: warning: leak of ‘nbalise’ [CWE-401] [-Wanalyzer-malloc-leak]
69 | }
| ^
‘newBalise’: event 1
|
| 55 | Balise* nbalise = malloc(sizeof(Balise));
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
|
‘newBalise’: events 2-3
|
| 57 | nbalise->suivant = NULL;
| | ^
| | |
| | (2) assuming ‘nbalise’ is non-NULL
|......
| 69 | }
| | ~
| | |
| | (3) ‘nbalise’ leaks here; was allocated at (1)
|
ps.c: In function ‘fgetXML’:
ps.c:76:13: warning: leak of ‘bal’ [CWE-401] [-Wanalyzer-malloc-leak]
76 | for(bal = start; index_for < start->len_suiv; bal = &bal->suivant[index_for++]){
| ~~~~^~~~~~~
‘fgetXML’: events 1-2
|
| 73 | Balise *bal = malloc(sizeof(Balise));
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
|......
| 76 | for(bal = start; index_for < start->len_suiv; bal = &bal->suivant[index_for++]){
| | ~~~~~~~~~~~
| | |
| | (2) ‘bal’ leaks here; was allocated at (1)
|
ps.c: In function ‘main’:
ps.c:88:5: warning: dereference of possibly-NULL ‘*html.debut.suivant’ [CWE-690] [-Wanalyzer-possible-null-dereference]
88 | printf("%s\n", html->debut.suivant[0].name);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
‘main’: events 1-2
|
| 84 | int main(int argc, char const *argv[])
| | ^~~~
| | |
| | (1) entry to ‘main’
| 85 | {
| 86 | HTML *html = init_HTML("test_xml_C.xml");
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) calling ‘init_HTML’ from ‘main’
|
+--> ‘init_HTML’: events 3-6
|
| 27 | HTML* init_HTML(char* name_xml) {
| | ^~~~~~~~~
| | |
| | (3) entry to ‘init_HTML’
|......
| 32 | balise->suivant = malloc(MAX_BAL_IN * sizeof(Balise));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) this call could return NULL
|......
| 40 | if((! html->f) || html == NULL || balise == NULL){
| | ~
| | |
| | (5) following ‘false’ branch...
|......
| 44 | return html;
| | ~~~~
| | |
| | (6) ...to here
|
<------+
|
‘main’: events 7-8
|
| 86 | HTML *html = init_HTML("test_xml_C.xml");
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (7) returning to ‘main’ from ‘init_HTML’
| 87 | newBalise("div", &html->debut);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (8) calling ‘newBalise’ from ‘main’
|
+--> ‘newBalise’: events 9-13
|
| 54 | void newBalise(char* name_b, Balise* parent) {
| | ^~~~~~~~~
| | |
| | (9) entry to ‘newBalise’
|......
| 65 | parent->suivant[(parent->index < MAX_BAL_IN) ? parent->index : MAX_BAL_IN - 1] = *nbalise;
| | ~ ~~~~~~~~~~~~~
| | | |
| | | (11) ...to here
| | (10) following ‘true’ branch...
| 66 | parent->index+= (parent->index < MAX_BAL_IN) ? 1 : -1;
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (12) following ‘true’ branch...
| | (13) ...to here
|
<------+
|
‘main’: events 14-15
|
| 87 | newBalise("div", &html->debut);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (14) possible return of NULL to ‘main’ from ‘newBalise’
| 88 | printf("%s\n", html->debut.suivant[0].name);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (15) ‘*html.debut.suivant’ could be NULL: unchecked value from (4)
|
et sinon tu peux toujours passer ton code sur valgrind :
$ valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./ps
==35854== Memcheck, a memory error detector
==35854== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==35854== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==35854== Command: ./ps
==35854==
==35854==
==35854== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==35854== Bad permissions for mapped region at address 0x10A006
==35854== at 0x4844DA8: __strncpy_sse2_unaligned (vg_replace_strmem.c:567)
==35854== by 0x1093AC: newBalise (ps.c:59)
==35854== by 0x109559: main (ps.c:87)
==35854==
sans lire une seule ligne de ton code, je peux te dire que tu utilises mal strncpy non seulement à cause du warning mais aussi de valgrind qui pointe cette ligne …
il va falloir apprendre à débuguer sans passer par un forum et peut-être aussi à limiter ton enthousiasme et t'attaquer à des programmes plus simples.
ta structure Balise contient un champ name q2ui est un pointeur sur char. Tu l'utilises sans l'initialiser ; il te faudrait par exemple allouer un peu de mémoire pour pouvoir y copier ce que tu veux.
ta structure Balise contient un champ name q2ui est un pointeur sur char. Tu l'utilises sans l'initialiser ; il te faudrait par exemple allouer un peu de mémoire pour pouvoir y copier ce que tu veux.
je ne comprends pas , je l'ai fait depuis longtemps:
Pour en revenir à ta question initiale, La façon dont tu utilises strncpy , fait que tu utiliserais strcpy ça ferait (presque *) pareil !
* presque, parce que tu ne tiens pas compte du caractère de fin de chaîne.
Pour strncpy si on met une taille, c'est pour ne pas déborder dans le buffer de destination, alors que toi tu n'en tiens pas compte de la façon dont tu procèdes.
Et au passage strncpy est probablement une des fonctions les plus pourries de la bibliothèque du C. Elle ne fait pas ce qu'on pense, en général on recommande l'utilisation de snprintf ou strlcpy (extension BSD qui va devrait être dans POSIX bientôt).
git is great because Linus did it, mercurial is better because he didn't.
Et au passage strncpy est probablement une des fonctions les plus pourries de la bibliothèque du C. Elle ne fait pas ce qu'on pense, en général on recommande l'utilisation de snprintf ou strlcpy (extension BSD qui va devrait être dans POSIX bientôt).
en faite j'ai réussi sans ses fonctions: j'ai remplacé les malloc par les [] et ca a marché je ne sais pas pourquoi
Le programmeur solitaire a écrit:
> [...] et ca a marché je ne sais pas pourquoi
Bonne chance et bon courage pour la suite.
Il faudrait suivre un cours et ne pas t'attaquer à quelque chose qui est pour l'instant hors de la portée de ta compréhension du C.
Et au passage strncpy est probablement une des fonctions les plus pourries de la bibliothèque du C. Elle ne fait pas ce qu'on pense, en général on recommande l'utilisation de snprintf ou strlcpy (extension BSD qui va devrait être dans POSIX bientôt).
asprintf finira un jour par arriver dans le standard du langage
ISO/IEC TR 24731 provides alternative functions for the C library that promote safer, more secure programming. ISO/IEC TR 24731-1 provides simple replacement functions for the library functions of ISO/IEC 9899:1999 that provide bounds checking. Those functions can be used as simple replacements for the original library functions in legacy code. ISO/IEC TR 24731-2:2010 presents replacements for many of these functions that use dynamically allocated memory to ensure that buffer overflow does not occur.
(on pourrait aussi imaginer une version qui, comme getline(), alloue/utilise/agrandit au besoin un buffer alloué dynamiquement)
- Edité par michelbillaud 8 juillet 2021 à 11:38:07
en faite j'ai réussi sans ses fonctions: j'ai remplacé les malloc par les [] et ca a marché je ne sais pas pourquoi
Un pointeur sur char n'est pas la même chose d'un tableau. Donc, lorsque tu utilises l'opérateur sizeof sur l'un ou l'autre, il est normal d'obtenir des résultats différents.
Tu as la taille du pointeur qui s'affiche, et non pas la taille occupée par les données pointées. Lorsque tu utilises un pointeur sur char, tu ne peux pas utiliser sizeof ni pour déterminer la longueur d'une chaîne, ni pour déterminer l'espace mémoire alloué sur ce pointeur. Pour disposer de la taille de l'espace mémoire alloué sur un pointeur, tu dois conserver cette information au moment où tu alloues la mémoire.
Pour une chaîne C, sizeof déterminera par contre bien l'espace mémoire disponible pour la chaîne s'il s'agit d'un tableau.
Ensuite, cela a été dit, mais je ne suis pas certain que cela ait cliqué dans ton esprit, si tu décides d'utiliser strncpy() bien qu'elle soit très imparfaite :
la taille à passer en 3ème paramètre est la taille maximale des données à copier dans l'espace mémoire indiqué en 1er paramètre (destination) à partir de l'espace mémoire en 2ème paramètre (source)
tu dois donc t'assurer de ne pas dépasser cette capacité au 1er paramètre et d'être en mesure de terminer la chaîne
tu dois t'assurer que tu termines la chaîne C, parce que strncpy() ne le fait pas pour toi si la destination est plus petite
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
le code FAIT le bonheur (pour moi en tous cas)
le code FAIT le bonheur (pour moi en tous cas)
le code FAIT le bonheur (pour moi en tous cas)
git is great because Linus did it, mercurial is better because he didn't.
le code FAIT le bonheur (pour moi en tous cas)
le code FAIT le bonheur (pour moi en tous cas)
le code FAIT le bonheur (pour moi en tous cas)
le code FAIT le bonheur (pour moi en tous cas)
git is great because Linus did it, mercurial is better because he didn't.
le code FAIT le bonheur (pour moi en tous cas)