warning: function returns address of local variable
65 réponses
pere.noel
à la compile d'un ensemble de fonctions + main, j'ai le message de
warning :
function returns address of local variable
pour la fonction "target_path_normalize"
elle retourne ce path normalisé :
target_path_normalized = /Users/yvon/work/.headers toto/CFArray.h
cette fonction "marche" mais je me demande quel risque je prends en
laissant trainer ce warning
le contexte : avant l'utilisation de cette fonction, j'en utilise une
autre "target_path_check" qui retourne NULL si le path n'est pas absolu
et accessoirement supprime le "/" en fin de chaîne s'il existe.
--- target_path_normalize ---------------------------------------------
char* target_path_normalize(const char* target_path)
{
int trente_deux = 32; /* maximum de répertoires traversés */
int mille_vingt_quatre = 1024; /* taille maximum d'un path */
char p[mille_vingt_quatre]="";
char *q;
char *token;
const char needle[] = "/";
const char *dot = ".";
const char *dotdot = "..";
int j;
q = strdup(target_path);
j = 0;
char *pieces[trente_deux];
// initialisation des éléments du tableau à NULL
while(j < trente_deux) {
pieces[j] = NULL;
j++;
}
// démarrage du découpage de q (target_path)
token = strtok(q, needle);
j = 0;
// découpage de q (target_path)
while(token != NULL) {
// si ".." on décrémente j equivalent à cd ..
// si "." on ne fait rien
// si différent de ".." et de "." on enregistre token dans
pieces[j] et on incrémente j
if(strcmp(token, dotdot) == 0) {
j--;
} else if(strcmp(token, dot) != 0) {
pieces[j]=token;
j++;
}
token = strtok(NULL, needle);
}
j = 0;
// concaténation de "/" (needle) et de pieces[j] jusqu'à épuisement
(quand pieces[j] == NULL)
while(pieces[j] != NULL) {
strcat(p, needle);
strcat(p, pieces[j]);
j++;
}
return p;
}
-----------------------------------------------------------------------
donc c'est le "return p" qui pose pb à la compil mais pas à
l'utilisation.
--
une bévue
à la compile d'un ensemble de fonctions + main, j'ai le message de warning : function returns address of local variable pour la fonction "target_path_normalize"
elle retourne ce path normalisé : target_path_normalized = /Users/yvon/work/.headers toto/CFArray.h
cette fonction "marche" mais je me demande quel risque je prends en laissant trainer ce warning
----------------------------------------------------------------------- donc c'est le "return p" qui pose pb à la compil mais pas à l'utilisation.
Declare la variable p en static
=?ISO-8859-1?Q?Une_bévue?= a écrit
à la compile d'un ensemble de fonctions + main, j'ai le message de
warning :
function returns address of local variable
pour la fonction "target_path_normalize"
à la compile d'un ensemble de fonctions + main, j'ai le message de warning : function returns address of local variable pour la fonction "target_path_normalize"
elle retourne ce path normalisé : target_path_normalized = /Users/yvon/work/.headers toto/CFArray.h
cette fonction "marche" mais je me demande quel risque je prends en laissant trainer ce warning
----------------------------------------------------------------------- donc c'est le "return p" qui pose pb à la compil mais pas à l'utilisation.
Declare la variable p en static
Harpo
Une bévue wrote:
à la compile d'un ensemble de fonctions + main, j'ai le message de warning : function returns address of local variable pour la fonction "target_path_normalize" (...)
cette fonction "marche" mais je me demande quel risque je prends en laissant trainer ce warning
Cette fonction ne marche qu'en apparence. En fait elle retourne l'adresse de quelque chose qui peut être considérée comme n'existant plus. Le comportement est indéfini (ici on dit souvent UB (undefined behaviour)). Tu changes de version de compilateur, ça pourra ne pas marcher, si tu intercales l'appel d'une autre fonction entre le moment ou ta fonction retourne et celui où tu déréférence le pointeur, il y a de bonnes chances que ça ne marche pas, i.e que tu aies des données fausses, que tu ne t'en aperçoive pas tout de suite et/ou que tu passes du temps à débugger.
donc c'est le "return p" qui pose pb à la compil mais pas à l'utilisation.
Malheureusement les tests ne permettent pas toujours de voir ce genre d'erreur.
-- http://patrick.davalan.free.fr/
Une bévue wrote:
à la compile d'un ensemble de fonctions + main, j'ai le message de
warning :
function returns address of local variable
pour la fonction "target_path_normalize"
(...)
cette fonction "marche" mais je me demande quel risque je prends en
laissant trainer ce warning
Cette fonction ne marche qu'en apparence.
En fait elle retourne l'adresse de quelque chose qui peut être
considérée comme n'existant plus. Le comportement est indéfini (ici on
dit souvent UB (undefined behaviour)).
Tu changes de version de compilateur, ça pourra ne pas marcher, si tu
intercales l'appel d'une autre fonction entre le moment ou ta fonction
retourne et celui où tu déréférence le pointeur, il y a de bonnes
chances que ça ne marche pas, i.e que tu aies des données fausses, que
tu ne t'en aperçoive pas tout de suite et/ou que tu passes du temps à
débugger.
donc c'est le "return p" qui pose pb à la compil mais pas à
l'utilisation.
Malheureusement les tests ne permettent pas toujours de voir ce genre
d'erreur.
à la compile d'un ensemble de fonctions + main, j'ai le message de warning : function returns address of local variable pour la fonction "target_path_normalize" (...)
cette fonction "marche" mais je me demande quel risque je prends en laissant trainer ce warning
Cette fonction ne marche qu'en apparence. En fait elle retourne l'adresse de quelque chose qui peut être considérée comme n'existant plus. Le comportement est indéfini (ici on dit souvent UB (undefined behaviour)). Tu changes de version de compilateur, ça pourra ne pas marcher, si tu intercales l'appel d'une autre fonction entre le moment ou ta fonction retourne et celui où tu déréférence le pointeur, il y a de bonnes chances que ça ne marche pas, i.e que tu aies des données fausses, que tu ne t'en aperçoive pas tout de suite et/ou que tu passes du temps à débugger.
donc c'est le "return p" qui pose pb à la compil mais pas à l'utilisation.
Malheureusement les tests ne permettent pas toujours de voir ce genre d'erreur.
-- http://patrick.davalan.free.fr/
pere.noel
JustMe wrote:
Declare la variable p en static
merci mais là j'ai une erreur ))) :
~/work/C/essais/save_path_array_new%> cc -W -Wall -Wextra -Wuninitialized -Wstrict-prototypes -Wmissing-prototypes -pedantic -stdÉ9 -O2 -pipe -o save_path_array_new save_path_array_new.c save_path_array_new.c: In function 'target_path_normalize': save_path_array_new.c:66: error: storage size of 'p' isn't constant
j'ai juste changé :
const int dirs_nbr_max = 32; /* maximum de répertoires traversés */ const int path_size_max = 1024; /* taille maximum d'un path */ static char p[path_size_max];
pourquoi donc gcc me dit "storage size of 'p' isn't constant" alors que j'ai :
const int path_size_max = 1024; /* taille maximum d'un path */ static char p[path_size_max];
bien sûr si je met :
static char p[1024];
=> ni warning ni erreur, donc ça signifie qu'une const int... n'est pas vue comme une constante ???
je dois définir dans mon .h cette constante ???
en utilisant : long path_max = pathconf("/", _PC_PATH_MAX);
???
si j'ajoute dans mon .h : # define PATH_SIZE_MAX pathconf("/", _PC_PATH_MAX)
avec dans mon .c : static char p[PATH_SIZE_MAX];
j'ai toujours le pb "'p' isn't constant"
alors que : printf("%ldn", PATH_SIZE_MAX);
me donne bien 1024... -- une bévue
JustMe <pasdespam@merci.beaucoup.con> wrote:
Declare la variable p en static
merci mais là j'ai une erreur ))) :
~/work/C/essais/save_path_array_new%> cc -W -Wall -Wextra
-Wuninitialized -Wstrict-prototypes -Wmissing-prototypes -pedantic
-stdÉ9 -O2 -pipe -o save_path_array_new save_path_array_new.c
save_path_array_new.c: In function 'target_path_normalize':
save_path_array_new.c:66: error: storage size of 'p' isn't constant
j'ai juste changé :
const int dirs_nbr_max = 32; /* maximum de répertoires traversés */
const int path_size_max = 1024; /* taille maximum d'un path */
static char p[path_size_max];
pourquoi donc gcc me dit "storage size of 'p' isn't constant" alors que
j'ai :
const int path_size_max = 1024; /* taille maximum d'un path */
static char p[path_size_max];
bien sûr si je met :
static char p[1024];
=> ni warning ni erreur, donc ça signifie qu'une const int... n'est pas
vue comme une constante ???
je dois définir dans mon .h cette constante ???
en utilisant :
long path_max = pathconf("/", _PC_PATH_MAX);
???
si j'ajoute dans mon .h :
# define PATH_SIZE_MAX pathconf("/", _PC_PATH_MAX)
~/work/C/essais/save_path_array_new%> cc -W -Wall -Wextra -Wuninitialized -Wstrict-prototypes -Wmissing-prototypes -pedantic -stdÉ9 -O2 -pipe -o save_path_array_new save_path_array_new.c save_path_array_new.c: In function 'target_path_normalize': save_path_array_new.c:66: error: storage size of 'p' isn't constant
j'ai juste changé :
const int dirs_nbr_max = 32; /* maximum de répertoires traversés */ const int path_size_max = 1024; /* taille maximum d'un path */ static char p[path_size_max];
pourquoi donc gcc me dit "storage size of 'p' isn't constant" alors que j'ai :
const int path_size_max = 1024; /* taille maximum d'un path */ static char p[path_size_max];
bien sûr si je met :
static char p[1024];
=> ni warning ni erreur, donc ça signifie qu'une const int... n'est pas vue comme une constante ???
je dois définir dans mon .h cette constante ???
en utilisant : long path_max = pathconf("/", _PC_PATH_MAX);
???
si j'ajoute dans mon .h : # define PATH_SIZE_MAX pathconf("/", _PC_PATH_MAX)
alors là, ce que je ne pige pas c'est qu'après "free(str3);" le "printf("str3: %sn", str3);" donne le m^me résultat que le printf précédent soit : ~/work/C/essais/strcat_test%> ./strcat_test str3: Hello World str3: Hello World
??? -- une bévue
Harpo <invalid@invalid.invalid> wrote:
#define A B
fait remplacer 'A' par 'B'
Dans ton cas 'PATH_SIZE_MAX' par
'pathconf("/", _PC_PATH_MAX)'
tu as donc
static char p[pathconf("/", _PC_PATH_MAX)];
et pathconf(...) ne semble pas être une expression constante.
ouais j'en passe donc par calloc dans un petit bout d'essai :
alors là, ce que je ne pige pas c'est qu'après "free(str3);" le
"printf("str3: %sn", str3);" donne le m^me résultat que le printf
précédent soit :
~/work/C/essais/strcat_test%> ./strcat_test
str3: Hello World
str3: Hello World
alors là, ce que je ne pige pas c'est qu'après "free(str3);" le "printf("str3: %sn", str3);" donne le m^me résultat que le printf précédent soit : ~/work/C/essais/strcat_test%> ./strcat_test str3: Hello World str3: Hello World
??? -- une bévue
johann.d
"Une bévue" a écrit dans le message de news:1hlaxg1.lsc8tbnkdf4N%
alors là, ce que je ne pige pas c'est qu'après "free(str3);" le "printf("str3: %sn", str3);" donne le m^me résultat que le printf précédent soit : ~/work/C/essais/strcat_test%> ./strcat_test str3: Hello World str3: Hello World
C'est parce que le garbagge collector n'est pas encore passé...
-- Johann.D
"Une bévue" <pere.noel@laponie.com.invalid> a écrit dans le message de
news:1hlaxg1.lsc8tbnkdf4N%pere.noel@laponie.com.invalid...
alors là, ce que je ne pige pas c'est qu'après "free(str3);" le
"printf("str3: %sn", str3);" donne le m^me résultat que le printf
précédent soit :
~/work/C/essais/strcat_test%> ./strcat_test
str3: Hello World
str3: Hello World
C'est parce que le garbagge collector n'est pas encore passé...
"Une bévue" a écrit dans le message de news:1hlaxg1.lsc8tbnkdf4N%
alors là, ce que je ne pige pas c'est qu'après "free(str3);" le "printf("str3: %sn", str3);" donne le m^me résultat que le printf précédent soit : ~/work/C/essais/strcat_test%> ./strcat_test str3: Hello World str3: Hello World
C'est parce que le garbagge collector n'est pas encore passé...
-- Johann.D
pere.noel
johann.d wrote:
C'est parce que le garbagge collector n'est pas encore passé...
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
-- une bévue
johann.d
"Une bévue" a écrit dans le message de news:1hlb032.r8khcm1mrgvx0N%
johann.d wrote:
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
Bien dit.
C'est "simplement" que tu d'attends à ce que free fasse quelque chose, alors qu'en pratique il ne fait quasiment rien... Le malloc te réserve un bout de mémoire et t'en donne l'adresse. Le free annule la réservation du bout de mémoire. Dans l'immense majorité des cas il ne va rien se passer d'autre, surtout si tu ne fais pas d'autre allocation par la suite.
Moralité, après le free tu effectues un accès à une zone mémoire qui ne t'appartient plus, cela n'implique pas pour autant que la zone mémoire aura été modifiée entre temps. En tout cas c'est un comportement indéfini (par contre, arrêtez moi si je me trompe, il y a des machines ou des cas où le gestionnaire de mémoire pourrait lever une exception ?).
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ptr = malloc(...); if (ptr == NULL) return AIEAIEAIE; /* do some job */ free(ptr); ptr = NULL; /* do some other job */ printf("%sn", ptr); // ici ptr est NULL donc l'erreur devrait être franche
-- Johann.D
"Une bévue" <pere.noel@laponie.com.invalid> a écrit dans le message de
news:1hlb032.r8khcm1mrgvx0N%pere.noel@laponie.com.invalid...
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
Bien dit.
C'est "simplement" que tu d'attends à ce que free fasse quelque chose, alors
qu'en pratique il ne fait quasiment rien...
Le malloc te réserve un bout de mémoire et t'en donne l'adresse.
Le free annule la réservation du bout de mémoire. Dans l'immense majorité
des cas il ne va rien se passer d'autre, surtout si tu ne fais pas d'autre
allocation par la suite.
Moralité, après le free tu effectues un accès à une zone mémoire qui ne
t'appartient plus, cela n'implique pas pour autant que la zone mémoire aura
été modifiée entre temps. En tout cas c'est un comportement indéfini (par
contre, arrêtez moi si je me trompe, il y a des machines ou des cas où le
gestionnaire de mémoire pourrait lever une exception ?).
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ptr = malloc(...);
if (ptr == NULL) return AIEAIEAIE;
/* do some job */
free(ptr);
ptr = NULL;
/* do some other job */
printf("%sn", ptr); // ici ptr est NULL donc l'erreur devrait être franche
"Une bévue" a écrit dans le message de news:1hlb032.r8khcm1mrgvx0N%
johann.d wrote:
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
Bien dit.
C'est "simplement" que tu d'attends à ce que free fasse quelque chose, alors qu'en pratique il ne fait quasiment rien... Le malloc te réserve un bout de mémoire et t'en donne l'adresse. Le free annule la réservation du bout de mémoire. Dans l'immense majorité des cas il ne va rien se passer d'autre, surtout si tu ne fais pas d'autre allocation par la suite.
Moralité, après le free tu effectues un accès à une zone mémoire qui ne t'appartient plus, cela n'implique pas pour autant que la zone mémoire aura été modifiée entre temps. En tout cas c'est un comportement indéfini (par contre, arrêtez moi si je me trompe, il y a des machines ou des cas où le gestionnaire de mémoire pourrait lever une exception ?).
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ptr = malloc(...); if (ptr == NULL) return AIEAIEAIE; /* do some job */ free(ptr); ptr = NULL; /* do some other job */ printf("%sn", ptr); // ici ptr est NULL donc l'erreur devrait être franche