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
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ben oui, je sais ça.
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
MAIS gros prob le ptr, dans mon cas est la valeur retournée ...
en gros, pour l'instant, je fais ça (sans le free))) :
char* target_path_dirname(const char* target_path) { [...] p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; } [...] return p; }
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
[...]
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; }
// appel de target_path_dirname int ierr = target_path_dirname(const char* target_path, char* p) { p = "machin_truc_muche"; return ierr; }
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ben oui, je sais ça.
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
MAIS gros prob le ptr, dans mon cas est la valeur retournée ...
en gros, pour l'instant, je fais ça (sans le free))) :
char* target_path_dirname(const char* target_path) {
[...]
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char));
if (p == NULL)
{ /* l'allocation a echoué: */
/* message d'erreur et arrêt du programme */
printf ("Malloc failed !n");
return NULL;
}
[...]
return p;
}
je ne vois pas trop comment m'en sortir sinon en définissant p à
l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
[...]
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char));
if (p == NULL)
{ /* l'allocation a echoué: */
/* message d'erreur et arrêt du programme */
printf ("Malloc failed !n");
return NULL;
}
// appel de target_path_dirname
int ierr = target_path_dirname(const char* target_path, char* p) {
p = "machin_truc_muche";
return ierr;
}
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ben oui, je sais ça.
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
MAIS gros prob le ptr, dans mon cas est la valeur retournée ...
en gros, pour l'instant, je fais ça (sans le free))) :
char* target_path_dirname(const char* target_path) { [...] p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; } [...] return p; }
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
[...]
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; }
// appel de target_path_dirname int ierr = target_path_dirname(const char* target_path, char* p) { p = "machin_truc_muche"; return ierr; }
[...]
free(p); p = NULL;
return EXIT_SUCCESS;
-- une bévue
Harpo
Une bévue wrote:
johann.d wrote:
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
Non, à moins que tu n'utilises un garbage collector pour remplacer malloc/free. Ca ne veut pas dire que les données désalloués ne sont pas accessibles, En fait cela dépend de pas mal. Une donnée libérée peut être dans ton espace alloué pour le process, il peut y avoir un mappingentre une adresse virtuelle et une adresse physique.
Pour simplifier un peu excessivement (et ce n'est pas toujours comme ça) mais le principe y est, la mémoire virtuelle est allouée par page (souvent 4096 bytes mais ça dépend d la plateforme) pour le process.
Si tu veux allouer de la mémoire pour y mettre 'blah' et qu'il n'y a plus de place dans une page allouée par le process, il y aura allocation d'une page, et tu pourras y mettre 'blah' à l'adresse qu'a renvoyé malloc(). Si ensuite tu alloues de la place pour mettre 'Hello World!', comme il reste de la place sur la page, malloc te renverra une adresse dans cette page, mettons un peu après 'blah'.
Quand tu libères la mémoire dans laquelle tu as mis 'hello World!', la page ne peut pas être libérée parce qu'il y a 'blah' que tu tiens à retrouver plus tard. La page n'est pas libérée et déréférencer un pointeur sur cette page ne génère pas d'interruption au niveau du processeur puisque l'adresse de la page peut être traduite par des circuits appropriés, si tu n'a rien fait entre le moment ou tu as libéré la page et le momnt où tu y accède, tu peux retrouver 'Hello World!'(ça doit être fréquent), ou autre chose. Accéder à de la mémoire libérée est un comportement indéterminé. Dans le meilleur des cas tu as SegFault, sinon tu peux avoir tout où n'importe quoi.
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
Non, à moins que tu n'utilises un garbage collector pour remplacer
malloc/free.
Ca ne veut pas dire que les données désalloués ne sont pas accessibles,
En fait cela dépend de pas mal.
Une donnée libérée peut être dans ton espace alloué pour le process, il
peut y avoir un mappingentre une adresse virtuelle et une adresse
physique.
Pour simplifier un peu excessivement (et ce n'est pas toujours comme ça)
mais le principe y est, la mémoire virtuelle est allouée par page
(souvent 4096 bytes mais ça dépend d la plateforme) pour le process.
Si tu veux allouer de la mémoire pour y mettre 'blah' et qu'il n'y a
plus de place dans une page allouée par le process, il y aura
allocation d'une page, et tu pourras y mettre 'blah' à l'adresse qu'a
renvoyé malloc().
Si ensuite tu alloues de la place pour mettre 'Hello World!', comme il
reste de la place sur la page, malloc te renverra une adresse dans
cette page, mettons un peu après 'blah'.
Quand tu libères la mémoire dans laquelle tu as mis 'hello World!', la
page ne peut pas être libérée parce qu'il y a 'blah' que tu tiens à
retrouver plus tard. La page n'est pas libérée et déréférencer un
pointeur sur cette page ne génère pas d'interruption au niveau du
processeur puisque l'adresse de la page peut être traduite par des
circuits appropriés, si tu n'a rien fait entre le moment ou tu as
libéré la page et le momnt où tu y accède, tu peux retrouver 'Hello
World!'(ça doit être fréquent), ou autre chose.
Accéder à de la mémoire libérée est un comportement indéterminé. Dans le
meilleur des cas tu as SegFault, sinon tu peux avoir tout où n'importe
quoi.
C'est parce que le garbagge collector n'est pas encore passé...
ça n'existe pas en C non ???
Non, à moins que tu n'utilises un garbage collector pour remplacer malloc/free. Ca ne veut pas dire que les données désalloués ne sont pas accessibles, En fait cela dépend de pas mal. Une donnée libérée peut être dans ton espace alloué pour le process, il peut y avoir un mappingentre une adresse virtuelle et une adresse physique.
Pour simplifier un peu excessivement (et ce n'est pas toujours comme ça) mais le principe y est, la mémoire virtuelle est allouée par page (souvent 4096 bytes mais ça dépend d la plateforme) pour le process.
Si tu veux allouer de la mémoire pour y mettre 'blah' et qu'il n'y a plus de place dans une page allouée par le process, il y aura allocation d'une page, et tu pourras y mettre 'blah' à l'adresse qu'a renvoyé malloc(). Si ensuite tu alloues de la place pour mettre 'Hello World!', comme il reste de la place sur la page, malloc te renverra une adresse dans cette page, mettons un peu après 'blah'.
Quand tu libères la mémoire dans laquelle tu as mis 'hello World!', la page ne peut pas être libérée parce qu'il y a 'blah' que tu tiens à retrouver plus tard. La page n'est pas libérée et déréférencer un pointeur sur cette page ne génère pas d'interruption au niveau du processeur puisque l'adresse de la page peut être traduite par des circuits appropriés, si tu n'a rien fait entre le moment ou tu as libéré la page et le momnt où tu y accède, tu peux retrouver 'Hello World!'(ça doit être fréquent), ou autre chose. Accéder à de la mémoire libérée est un comportement indéterminé. Dans le meilleur des cas tu as SegFault, sinon tu peux avoir tout où n'importe quoi.
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 ?).
Quand on utilise un printf, ça ne passe pas par le gestionnaire de mémoire. Il peut lever une exception où râler d'une manière ou d'une autre car il a pu se reservir de la mémoire pour y mettre ses pointeurs de chaînage de memoire allouée et peut s'apercevoir qu'un pointeur a été corrompu si on a écrit dans le machin. Il peut donc gueuler à un malloc ou à un free suivant. Où alors la page n'existe plus et il y aura une exception à son accès.
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
Voilà, excellente habitude qui ne coûte pas cher.
-- http://patrick.davalan.free.fr/
johann.d wrote:
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 ?).
Quand on utilise un printf, ça ne passe pas par le gestionnaire de
mémoire.
Il peut lever une exception où râler d'une manière ou d'une autre car il
a pu se reservir de la mémoire pour y mettre ses pointeurs de chaînage
de memoire allouée et peut s'apercevoir qu'un pointeur a été corrompu
si on a écrit dans le machin.
Il peut donc gueuler à un malloc ou à un free suivant.
Où alors la page n'existe plus et il y aura une exception à son accès.
Une bonne habitude est de toujours suivre un free d'une affectation à
NULL :
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 ?).
Quand on utilise un printf, ça ne passe pas par le gestionnaire de mémoire. Il peut lever une exception où râler d'une manière ou d'une autre car il a pu se reservir de la mémoire pour y mettre ses pointeurs de chaînage de memoire allouée et peut s'apercevoir qu'un pointeur a été corrompu si on a écrit dans le machin. Il peut donc gueuler à un malloc ou à un free suivant. Où alors la page n'existe plus et il y aura une exception à son accès.
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
Voilà, excellente habitude qui ne coûte pas cher.
-- http://patrick.davalan.free.fr/
pere.noel
Harpo wrote:
Non, à moins que tu n'utilises un garbage collector pour remplacer malloc/free. Ca ne veut pas dire que les données désalloués ne sont pas accessibles, En fait cela dépend de pas mal. Une donnée libérée peut être dans ton espace alloué pour le process, il peut y avoir un mappingentre une adresse virtuelle et une adresse physique.
Pour simplifier un peu excessivement (et ce n'est pas toujours comme ça) mais le principe y est, la mémoire virtuelle est allouée par page (souvent 4096 bytes mais ça dépend d la plateforme) pour le process.
Si tu veux allouer de la mémoire pour y mettre 'blah' et qu'il n'y a plus de place dans une page allouée par le process, il y aura allocation d'une page, et tu pourras y mettre 'blah' à l'adresse qu'a renvoyé malloc(). Si ensuite tu alloues de la place pour mettre 'Hello World!', comme il reste de la place sur la page, malloc te renverra une adresse dans cette page, mettons un peu après 'blah'.
Quand tu libères la mémoire dans laquelle tu as mis 'hello World!', la page ne peut pas être libérée parce qu'il y a 'blah' que tu tiens à retrouver plus tard. La page n'est pas libérée et déréférencer un pointeur sur cette page ne génère pas d'interruption au niveau du processeur puisque l'adresse de la page peut être traduite par des circuits appropriés, si tu n'a rien fait entre le moment ou tu as libéré la page et le momnt où tu y accède, tu peux retrouver 'Hello World!'(ça doit être fréquent), ou autre chose. Accéder à de la mémoire libérée est un comportement indéterminé. Dans le meilleur des cas tu as SegFault, sinon tu peux avoir tout où n'importe quoi.
je vois le shimiliblick ))) -- une bévue
Harpo <invalid@invalid.invalid> wrote:
Non, à moins que tu n'utilises un garbage collector pour remplacer
malloc/free.
Ca ne veut pas dire que les données désalloués ne sont pas accessibles,
En fait cela dépend de pas mal.
Une donnée libérée peut être dans ton espace alloué pour le process, il
peut y avoir un mappingentre une adresse virtuelle et une adresse
physique.
Pour simplifier un peu excessivement (et ce n'est pas toujours comme ça)
mais le principe y est, la mémoire virtuelle est allouée par page
(souvent 4096 bytes mais ça dépend d la plateforme) pour le process.
Si tu veux allouer de la mémoire pour y mettre 'blah' et qu'il n'y a
plus de place dans une page allouée par le process, il y aura
allocation d'une page, et tu pourras y mettre 'blah' à l'adresse qu'a
renvoyé malloc().
Si ensuite tu alloues de la place pour mettre 'Hello World!', comme il
reste de la place sur la page, malloc te renverra une adresse dans
cette page, mettons un peu après 'blah'.
Quand tu libères la mémoire dans laquelle tu as mis 'hello World!', la
page ne peut pas être libérée parce qu'il y a 'blah' que tu tiens à
retrouver plus tard. La page n'est pas libérée et déréférencer un
pointeur sur cette page ne génère pas d'interruption au niveau du
processeur puisque l'adresse de la page peut être traduite par des
circuits appropriés, si tu n'a rien fait entre le moment ou tu as
libéré la page et le momnt où tu y accède, tu peux retrouver 'Hello
World!'(ça doit être fréquent), ou autre chose.
Accéder à de la mémoire libérée est un comportement indéterminé. Dans le
meilleur des cas tu as SegFault, sinon tu peux avoir tout où n'importe
quoi.
Non, à moins que tu n'utilises un garbage collector pour remplacer malloc/free. Ca ne veut pas dire que les données désalloués ne sont pas accessibles, En fait cela dépend de pas mal. Une donnée libérée peut être dans ton espace alloué pour le process, il peut y avoir un mappingentre une adresse virtuelle et une adresse physique.
Pour simplifier un peu excessivement (et ce n'est pas toujours comme ça) mais le principe y est, la mémoire virtuelle est allouée par page (souvent 4096 bytes mais ça dépend d la plateforme) pour le process.
Si tu veux allouer de la mémoire pour y mettre 'blah' et qu'il n'y a plus de place dans une page allouée par le process, il y aura allocation d'une page, et tu pourras y mettre 'blah' à l'adresse qu'a renvoyé malloc(). Si ensuite tu alloues de la place pour mettre 'Hello World!', comme il reste de la place sur la page, malloc te renverra une adresse dans cette page, mettons un peu après 'blah'.
Quand tu libères la mémoire dans laquelle tu as mis 'hello World!', la page ne peut pas être libérée parce qu'il y a 'blah' que tu tiens à retrouver plus tard. La page n'est pas libérée et déréférencer un pointeur sur cette page ne génère pas d'interruption au niveau du processeur puisque l'adresse de la page peut être traduite par des circuits appropriés, si tu n'a rien fait entre le moment ou tu as libéré la page et le momnt où tu y accède, tu peux retrouver 'Hello World!'(ça doit être fréquent), ou autre chose. Accéder à de la mémoire libérée est un comportement indéterminé. Dans le meilleur des cas tu as SegFault, sinon tu peux avoir tout où n'importe quoi.
"Une bévue" a écrit dans le message de news:1hlb1je.e1rbzq104uqqnN%
johann.d wrote:
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ben oui, je sais ça.
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
MAIS gros prob le ptr, dans mon cas est la valeur retournée ...
Ben... Où est le problème ? Tu retournes le ptr, et tu laisse la fonction appelante faire le free quand elle en aura marre, non ?
en gros, pour l'instant, je fais ça (sans le free))) :
char* target_path_dirname(const char* target_path) { [...] p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; } [...] return p; }
Petite remarques au passage mais je crois qu'on te les a signalé par ailleurs : sizeof (char) vaut toujours 1.
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
Pourquoi faire ???
Ca ne te convient pas ce genre de construction :
int ma_fonction(...) { char *tgt;
tgt = target_path_dirname(...); if (tgt == NULL) return -1;
[...]
free(tgt); tgt = NULL;
[...]
return 0; }
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; }
// appel de target_path_dirname int ierr = target_path_dirname(const char* target_path, char* p) { p = "machin_truc_muche"; return ierr; }
Là je ne comprends rien du tout...
Si tu veux "seulement" modifier target_path_dirname pour renvoyer un code d'erreur plutôt que le pointeur, "il suffit" de lui passer un pointeur sur le pointeur, non ?
int ma_fonction(...) { char *tgt = NULL; int ierr;
ierr = target_path_dirname(..., &tgt); if (ierr) return ierr; if (tgt == NULL) return -1;
[...]
free(tgt); tgt = NULL;
[...]
return 0; }
en écrivant bien évidemment target_path_dirname ainsi :
Une bonne habitude est de toujours suivre un free d'une affectation à
NULL :
ben oui, je sais ça.
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
MAIS gros prob le ptr, dans mon cas est la valeur retournée ...
Ben... Où est le problème ? Tu retournes le ptr, et tu laisse la fonction
appelante faire le free quand elle en aura marre, non ?
en gros, pour l'instant, je fais ça (sans le free))) :
char* target_path_dirname(const char* target_path) {
[...]
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char));
if (p == NULL)
{ /* l'allocation a echoué: */
/* message d'erreur et arrêt du programme */
printf ("Malloc failed !n");
return NULL;
}
[...]
return p;
}
Petite remarques au passage mais je crois qu'on te les a signalé par
ailleurs : sizeof (char) vaut toujours 1.
je ne vois pas trop comment m'en sortir sinon en définissant p à
l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
Pourquoi faire ???
Ca ne te convient pas ce genre de construction :
int ma_fonction(...) {
char *tgt;
tgt = target_path_dirname(...);
if (tgt == NULL) return -1;
[...]
free(tgt);
tgt = NULL;
[...]
return 0;
}
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char));
if (p == NULL)
{ /* l'allocation a echoué: */
/* message d'erreur et arrêt du programme */
printf ("Malloc failed !n");
return NULL;
}
// appel de target_path_dirname
int ierr = target_path_dirname(const char* target_path, char* p) {
p = "machin_truc_muche";
return ierr;
}
Là je ne comprends rien du tout...
Si tu veux "seulement" modifier target_path_dirname pour renvoyer un code
d'erreur plutôt que le pointeur, "il suffit" de lui passer un pointeur sur
le pointeur, non ?
int ma_fonction(...) {
char *tgt = NULL;
int ierr;
ierr = target_path_dirname(..., &tgt);
if (ierr) return ierr;
if (tgt == NULL) return -1;
[...]
free(tgt);
tgt = NULL;
[...]
return 0;
}
en écrivant bien évidemment target_path_dirname ainsi :
"Une bévue" a écrit dans le message de news:1hlb1je.e1rbzq104uqqnN%
johann.d wrote:
Une bonne habitude est de toujours suivre un free d'une affectation à NULL :
ben oui, je sais ça.
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
MAIS gros prob le ptr, dans mon cas est la valeur retournée ...
Ben... Où est le problème ? Tu retournes le ptr, et tu laisse la fonction appelante faire le free quand elle en aura marre, non ?
en gros, pour l'instant, je fais ça (sans le free))) :
char* target_path_dirname(const char* target_path) { [...] p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; } [...] return p; }
Petite remarques au passage mais je crois qu'on te les a signalé par ailleurs : sizeof (char) vaut toujours 1.
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
Pourquoi faire ???
Ca ne te convient pas ce genre de construction :
int ma_fonction(...) { char *tgt;
tgt = target_path_dirname(...); if (tgt == NULL) return -1;
[...]
free(tgt); tgt = NULL;
[...]
return 0; }
p = (char *) malloc (PATH_SIZE_MAX * sizeof (char)); if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL; }
// appel de target_path_dirname int ierr = target_path_dirname(const char* target_path, char* p) { p = "machin_truc_muche"; return ierr; }
Là je ne comprends rien du tout...
Si tu veux "seulement" modifier target_path_dirname pour renvoyer un code d'erreur plutôt que le pointeur, "il suffit" de lui passer un pointeur sur le pointeur, non ?
int ma_fonction(...) { char *tgt = NULL; int ierr;
ierr = target_path_dirname(..., &tgt); if (ierr) return ierr; if (tgt == NULL) return -1;
[...]
free(tgt); tgt = NULL;
[...]
return 0; }
en écrivant bien évidemment target_path_dirname ainsi :
Je crois que sizeof(char) vaut toujours 1, à vérifier.
if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL;
Cool !
} [...] return p; }
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là
p est retourné par valeur, comme toujours, ce qui fait que la fonction appelante aura l'adresse de la mémoire allouée. Je ne vois pas ce qui pose problème à moins que j'ai loupé un truc. Ta fonction m'a l'air bonne. Ce n'est pas comme si t'avais mis char p[] = "blah"; (blah étant alloué dans la pile) D'ailleurs je me demande même si char * p = "blah"; (blah étant alloué ailleurs que dans la pile) ne serait pas valide
Sinon, target_path n'est pas utilisé dans la fonction, de bonnes options de warning auraient du te le signaler.
-- http://patrick.davalan.free.fr/
Une bévue wrote:
en gros, pour l'instant, je fais ça (sans le free))) :
S'il doit retourner de la mémoire allouée, il vaut mieux qu'il ne la
libère pas avant de retourner, hein.
Je crois que sizeof(char) vaut toujours 1, à vérifier.
if (p == NULL)
{ /* l'allocation a echoué: */
/* message d'erreur et arrêt du programme */
printf ("Malloc failed !n");
return NULL;
Cool !
}
[...]
return p;
}
je ne vois pas trop comment m'en sortir sinon en définissant p à
l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là
p est retourné par valeur, comme toujours, ce qui fait que la fonction
appelante aura l'adresse de la mémoire allouée.
Je ne vois pas ce qui pose problème à moins que j'ai loupé un truc. Ta
fonction m'a l'air bonne.
Ce n'est pas comme si t'avais mis
char p[] = "blah";
(blah étant alloué dans la pile)
D'ailleurs je me demande même si
char * p = "blah";
(blah étant alloué ailleurs que dans la pile)
ne serait pas valide
Sinon, target_path n'est pas utilisé dans la fonction, de bonnes options
de warning auraient du te le signaler.
Je crois que sizeof(char) vaut toujours 1, à vérifier.
if (p == NULL) { /* l'allocation a echoué: */ /* message d'erreur et arrêt du programme */ printf ("Malloc failed !n"); return NULL;
Cool !
} [...] return p; }
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là
p est retourné par valeur, comme toujours, ce qui fait que la fonction appelante aura l'adresse de la mémoire allouée. Je ne vois pas ce qui pose problème à moins que j'ai loupé un truc. Ta fonction m'a l'air bonne. Ce n'est pas comme si t'avais mis char p[] = "blah"; (blah étant alloué dans la pile) D'ailleurs je me demande même si char * p = "blah"; (blah étant alloué ailleurs que dans la pile) ne serait pas valide
Sinon, target_path n'est pas utilisé dans la fonction, de bonnes options de warning auraient du te le signaler.
-- http://patrick.davalan.free.fr/
Harpo
Une bévue wrote:
Stéphane Goujet wrote:
sizeof(char) vaut toujours 1 (par définition).
oui, mais c'est plus zoli )))
J'ai parfois vu ça dans des programmes écrits par des dandies.
donc, si j'ai bien compris (je commence à me faire à C, ça commence à devenir amusant) :
free(mon_ptr);
libère la zone mémoire allouée à mon_ptr qui pointe la même adresse que ptr dans la fonction ma_fonction et donc les deux sont libérés car il ne font qu'un seul, c'est bien ça ???
si c'est vrai, j'ai fait un bon en avant )) (en C)
<snip/>
Petite remarques au passage mais je crois qu'on te les a signalé par ailleurs : sizeof (char) vaut toujours 1.
oui, mais je pense passer à autre chose que du char (utf8)...
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
<snip/>
Là je ne comprends rien du tout...
pas grave j'avais loupé un métro (voir + haut)
<snip/>
Ou alors c'est que je n'ai rien compris à ton besoin ???
non, non, tu as bien pigé, mon pb n'a rien de spécial ;-) -- une bévue
donc, si j'ai bien compris (je commence à me faire à C, ça commence à
devenir amusant) :
free(mon_ptr);
libère la zone mémoire allouée à mon_ptr qui pointe la même adresse que
ptr dans la fonction ma_fonction et donc les deux sont libérés car il ne
font qu'un seul, c'est bien ça ???
si c'est vrai, j'ai fait un bon en avant )) (en C)
<snip/>
Petite remarques au passage mais je crois qu'on te les a signalé par
ailleurs : sizeof (char) vaut toujours 1.
oui, mais je pense passer à autre chose que du char (utf8)...
je ne vois pas trop comment m'en sortir sinon en définissant p à
l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
<snip/>
Là je ne comprends rien du tout...
pas grave j'avais loupé un métro (voir + haut)
<snip/>
Ou alors c'est que je n'ai rien compris à ton besoin ???
non, non, tu as bien pigé, mon pb n'a rien de spécial ;-)
--
une bévue
donc, si j'ai bien compris (je commence à me faire à C, ça commence à devenir amusant) :
free(mon_ptr);
libère la zone mémoire allouée à mon_ptr qui pointe la même adresse que ptr dans la fonction ma_fonction et donc les deux sont libérés car il ne font qu'un seul, c'est bien ça ???
si c'est vrai, j'ai fait un bon en avant )) (en C)
<snip/>
Petite remarques au passage mais je crois qu'on te les a signalé par ailleurs : sizeof (char) vaut toujours 1.
oui, mais je pense passer à autre chose que du char (utf8)...
je ne vois pas trop comment m'en sortir sinon en définissant p à l'extérieur en ajoutant un paramètre à la function qqc dans ce goût là :
<snip/>
Là je ne comprends rien du tout...
pas grave j'avais loupé un métro (voir + haut)
<snip/>
Ou alors c'est que je n'ai rien compris à ton besoin ???
non, non, tu as bien pigé, mon pb n'a rien de spécial ;-) -- une bévue