Malloc qui recouvre un espace alloué à la compilation ?

Malloc qui recouvre un espace alloué à la compilation ? - C - Programmation

Marsh Posté le 08-04-2009 à 15:30:04    

Bonjour,
 
Je rencontre un problème qui m'a l'air assez "sioux".
 
J'ai un code source C dans lequel je déclare:

Code :
  1. main()
  2. {
  3.    float variable=0;
  4.    float * tab;
  5.    tab=malloc(10000*sizeof(float));
  6.    /* Fonction où je passe &variable et tab et qui contient une boucle affectant des valeurs à tab[i] */
  7. }


 
Pour l'instant j'ai mis un malloc(10000) au lieu d'un [] car à terme je compte rendre cette taille variable à l'exécution.
 
Le problème que je rencontre est que "variable" est alloué à l'adresse 0X0013fe9C, tandis que l'adresse pointée par tab est 0X0013fe0.
Résultat : à la 4é exécution de ma boucle (tab[3] pointe vers 0X0013fe9C, car dans mon case sizeof(float)=4) j'écrase "variable".
 
Ce que je ne comprends pas, c'est que d'après ce que j'ai compris, l'emplacement mémoire de "variable" est réservé à la compilation, tandis que celui pointé par tab, via le malloc est réservé à l'exécution. Je croyais que les deux étaient bien séparés. J'utilise VS Express 2008.
 
Merci d'avance pour votre aide précieuse,
Flo

Reply

Marsh Posté le 08-04-2009 à 15:30:04   

Reply

Marsh Posté le 08-04-2009 à 15:48:19    

Dans le cas présent, variable et tab sont des espaces en mémoire sur la pile (stack). Donc l'adresse précise n'est déterminée qu'au moment de l'éxécution.
 
Si ces champs avaient été déclarés en dehors d'une fonction, alors ils auraient été déclarés sur le tas (heap) et auraient eu une adresse fixée lors de la compilation (qui aurait ensuite été ajustée par le loader au moment du chargement du programme en mémoire).
 
Une petite erreur est de ne pas caster le retour du malloc(), d'ailleurs le compilateur devrait émettre un warning. Donc écrire :

tab=(float *)malloc(10000*sizeof(float));

Ensuite, il n'y a pas de raison pour que tab[x], avec x compris entre 0 et 99999, empiète sur les autres variables, car la notation avec les crochets est équivalente à (adresse trouvée dans tab) + x, et non pas à (adresse de tab) + x.

Message cité 1 fois
Message édité par olivthill le 08-04-2009 à 15:53:09
Reply

Marsh Posté le 08-04-2009 à 15:52:20    

Merci olivthill, j'allais corriger, bien sûr "variable" n'est pas statique donc sont emplacement est réservée à l'entrée dans le bloc, sur la pile.
 
Mais j'ai tout de même mon malloc qui réserve un emplacement déjà utilisé... et je ne comprends vraiment pas pourquoi.
 

Reply

Marsh Posté le 08-04-2009 à 15:54:50    

tab est égal à 0X0013fe0, ce qui est proche de l'adresse de variable. Mais ce qui compte est l'adresse indiquée à l'emplacement 0X0013fe0 (voir le complément d'explication dans mon message édité).

Reply

Marsh Posté le 08-04-2009 à 16:25:03    

@MKflo84, tu n'utiliserais pas &tab a la place de tab par hasard?
 
@olivhill, il n'est pas necessaire -- et beaucoup(*) considerent que c'est de mauvais style de le faire -- de caster le resultat de malloc en C  (ce serait necessaire en C++, un warning ou une erreur sur cette ligne en C resulte generalement d'un autre probleme, oublier d'inclure <stdlib.h> par exemple).
 
(*) ce n'est pas mon cas, mais je sais que je suis plutot dans la minorite.

Reply

Marsh Posté le 08-04-2009 à 17:06:21    

Merci "Un Programmeur", j'ai vérifié, je transmets bien "tab" à ma fonction.
 
Pour le cast, je l'avais mis dans mon code. Je ne l'ai juste pas recopié sachant que ça ne faisait pas de différence.
 
Lorsque je remplace mon malloc par un float tab[10000] (sans aucune autre modif), je n'ai pas de problème. L'emplacement mémoire du tableau est bien disjoint du reste. Là, vraiment je suis collé...

Reply

Marsh Posté le 08-04-2009 à 17:33:15    

Donne un exemple complet et aussi minimal que possible reproduisant ton probleme.

Reply

Marsh Posté le 08-04-2009 à 20:28:25    

0x13fe0 et 0x13fe9c ne sont pas proches du tout. Ou alors tu as oublié un 0 à la première.

Reply

Marsh Posté le 09-04-2009 à 09:30:41    

olivthill a écrit :

Une petite erreur est de ne pas caster le retour du malloc(),


Ce n'est pas une erreur. Il n'y a aucune raison, depuis C90, de caster le retour d'un malloc() en C. (et en C++, on utilise new).
 
http://mapage.noos.fr/emdel/notes.htm#malloc


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 09-04-2009 à 13:55:24    

Montre ton code, il y a forcément un endroit ou tu confond l'adresse du pointeur et l'adresse pointée par le pointeur. Ou alors, autre possibilité, tu as un truc dans ton code qui va écraser tab après ton malloc.
 
Tu devrais utiliser un debugger et regarder la valeur de tab juste après le malloc. Ce n'est certainement pas 0X0013fe0.


Message édité par matafan le 09-04-2009 à 13:55:34
Reply

Marsh Posté le 09-04-2009 à 13:55:24   

Reply

Marsh Posté le 10-04-2009 à 12:28:34    

MKflo84 a écrit :

Bonjour,
 
Je rencontre un problème qui m'a l'air assez "sioux".
 
J'ai un code source C dans lequel je déclare:

Code :
  1. main()
  2. {
  3.    float variable=0;
  4.    float * tab;
  5.    tab=malloc(10000*sizeof(float));
  6.    /* Fonction où je passe &variable et tab et qui contient une boucle affectant des valeurs à tab[i] */
  7. }


 
Pour l'instant j'ai mis un malloc(10000) au lieu d'un [] car à terme je compte rendre cette taille variable à l'exécution.
 
Le problème que je rencontre est que "variable" est alloué à l'adresse 0X0013fe9C, tandis que l'adresse pointée par tab est 0X0013fe0.
Résultat : à la 4é exécution de ma boucle (tab[3] pointe vers 0X0013fe9C, car dans mon case sizeof(float)=4) j'écrase "variable".
 
Ce que je ne comprends pas, c'est que d'après ce que j'ai compris, l'emplacement mémoire de "variable" est réservé à la compilation, tandis que celui pointé par tab, via le malloc est réservé à l'exécution. Je croyais que les deux étaient bien séparés. J'utilise VS Express 2008.
 
Merci d'avance pour votre aide précieuse,
Flo


 
J'ai recopié l'intégralité de ton code, j'ai rajouté qq printf() à la fin et chaque fois que j'ai lancé ce programme, j'ai eu des écarts de plusieurs milliers d'octets entre les 2 adresses.
 

MKflo84 a écrit :

Merci "Un Programmeur", j'ai vérifié, je transmets bien "tab" à ma fonction.


Tu veux bien nous montrer cette fonction et sa façon de gérer les paramètres reçus ???


Message édité par Sve@r le 10-04-2009 à 12:36:02

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed