Alléger un programme pour éviter de faire exploser la pile.

Alléger un programme pour éviter de faire exploser la pile. - C - Programmation

Marsh Posté le 28-06-2006 à 17:32:55    

Bonjour,
 
Je dévelloppe actuellement des apllis sous linux destiné à une cible embarqué de très faible taille (mémoire(2Mo flash), proc (55Mhz),...).
 
Mon problème est que l'appli sur laquel je travaille actuellement fait apparement explosé la pile de ma cible, alors qu'elle marche sans aucun pb sur ma machine de dévelloppement.
 
J'aimerais avoir vos suggestions pour pouvoir réduire la taille qu'occuppe mon programme dans la pile.
 
En fait j'ai un prog principal qui tourne mais quand je lui rajoute une fonction supplémentaire (fonction de post) qui se trouve dans un fichier à part, alors ca plante. Cette fonction fonctionne correctement sur ma cible lorsque je me contente de l'appeller depuis un simple programme de 2 lignes.
 
je vous met sur ftp le fichier concerné en espérent que vous m'aidiez a réduire l'occupation de se programme.
 
Lien : fichier
 
 
Merci d'avance


Message édité par Vilo5 le 28-06-2006 à 17:33:52
Reply

Marsh Posté le 28-06-2006 à 17:32:55   

Reply

Marsh Posté le 28-06-2006 à 19:26:55    

   char host[2000];
 
passe en malloc ça
 
    char head_buf[10000];
    char data_buf[50000];
    char enc_buf[5000];
 
ça
 
 /* Basic Auth info. */
 char token_buf[500];
    char buf[5000];
 
 
et ne fais aucune récursion (si tu en as)
 
 
 
 
 
 
 
 
 
 
 
static char b64_encode_table[64] = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',  /* 0-7 */
    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',  /* 8-15 */
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',  /* 16-23 */
    'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',  /* 24-31 */
    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',  /* 32-39 */
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v',  /* 40-47 */
    'w', 'x', 'y', 'z', '0', '1', '2', '3',  /* 48-55 */
    '4', '5', '6', '7', '8', '9', '+', '/'   /* 56-63 */
    };
 
static int b64_decode_table[256] = {
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
    52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
    15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
    -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
    41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
    };
 
 
la tu peux rajouter des jolis const
 

Reply

Marsh Posté le 28-06-2006 à 19:30:14    

t'as pas de main au fait ...

Reply

Marsh Posté le 29-06-2006 à 15:34:25    

Taz a écrit :

char host[2000];
 
passe en malloc ça
 
ça
 
 /* Basic Auth info. */
 char token_buf[500];
    char buf[5000];
 
 
et ne fais aucune récursion (si tu en as)


Ok ca je suis en train de le faire mais ca plante sur les :
 
    char head_buf[10000];
    char data_buf[50000];
    char enc_buf[5000];
 

Taz a écrit :


static char b64_encode_table[64] = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',  /* 0-7 */
    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',  /* 8-15 */
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',  /* 16-23 */
    'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',  /* 24-31 */
    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',  /* 32-39 */
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v',  /* 40-47 */
    'w', 'x', 'y', 'z', '0', '1', '2', '3',  /* 48-55 */
    '4', '5', '6', '7', '8', '9', '+', '/'   /* 56-63 */
    };
 
static int b64_decode_table[256] = {
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
    52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
    15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
    -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
    41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
    };
 
 
la tu peux rajouter des jolis const


Comment çà, je comprend pas ?
 

Taz a écrit :

t'as pas de main au fait ...


 
Ouais c'est normal, c'est pas le prog principale mais un fichier comportant des fonctions qui sont appellées depuis le prog principal.

Reply

Marsh Posté le 29-06-2006 à 15:42:33    

Vilo5 a écrit :

Ok ca je suis en train de le faire mais ca plante sur les :
 
    char head_buf[10000];
    char data_buf[50000];
    char enc_buf[5000];


Ben oui mais non, Taz te dis d'utiliser malloc, ca enlvera tes tableaux de la pile, où ils sont placés si tu les instancies de ta manière.
 

Vilo5 a écrit :


Comment çà, je comprend pas ?


 
Avec const, tes tableaux ne seront plus placés dans la pile.


Message édité par _darkalt3_ le 29-06-2006 à 15:43:07
Reply

Marsh Posté le 29-06-2006 à 16:15:26    

mais ils ne sont pas sur la pile, ils sont 'static'. le const est quand meme requis si ces tables ne sont pas modifiées

Reply

Marsh Posté le 29-06-2006 à 16:21:43    

ah oui zut j'avais pas vu.

Reply

Marsh Posté le 29-06-2006 à 16:48:21    

skelter a écrit :

mais ils ne sont pas sur la pile, ils sont 'static'. le const est quand meme requis si ces tables ne sont pas modifiées


 
Ok.
 
Enfin bon je suppose que c'est ma pile qui explose, c'est peut être autre chose mais je ne vois pas quoi.
 
En tout cas sur ma machine de développement ca marche mais pas sur la cible.
Par contre si je fais un bête programme comme le suivant pour appeller mes fonctions post alors ca marche :
 

Code :
  1. int main(void)
  2. {
  3. int num_site;
  4. int num_pm;
  5. long num_dossier;
  6. long num_carte;
  7. nums.num_site=246;
  8. nums.num_dossier=2003298; 
  9. nums.num_carte=603;
  10. nums.num_pm=1;
  11. pre_post(num_site, num_dossier, num_carte, num_pm);
  12. }


 
C''set donc bien en en reliant les fonctions post à mon prog principal (qui est bien plus gros que celui ci-dessus) que ca explose.
 
Biensure le prog principal fonctionne si je met en commentaire la ligne d'appel de la fonction post.

Message cité 2 fois
Message édité par Vilo5 le 29-06-2006 à 16:50:01
Reply

Marsh Posté le 29-06-2006 à 20:06:42    

Vilo5 a écrit :

Ok.
 
Enfin bon je suppose que c'est ma pile qui explose, c'est peut être autre chose mais je ne vois pas quoi.


 
renseigne toi sur le materiel cible, si le tas et la pile se partagent le meme segment dans la memoire flash alors le fait d'allouer dynamiquement pourrais ne rien changer, c'est peut etre un probleme de consommation de memoire

Message cité 1 fois
Message édité par skelter le 29-06-2006 à 20:07:56
Reply

Marsh Posté le 29-06-2006 à 22:47:05    

skelter a écrit :

renseigne toi sur le materiel cible, si le tas et la pile se partagent le meme segment dans la memoire flash


 :ouch:  :ouch:  :ouch: Absurdité. Les données ne sont pas en flash mais en RAM !

Message cité 1 fois
Message édité par Emmanuel Delahaye le 29-06-2006 à 22:47:19

---------------
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 29-06-2006 à 22:47:05   

Reply

Marsh Posté le 30-06-2006 à 00:16:04    

Emmanuel Delahaye a écrit :

:ouch:  :ouch:  :ouch: Absurdité. Les données ne sont pas en flash mais en RAM !


 
parce-que un engin ne peut pas avoir de memoire flash qui fait office de ram ??

Reply

Marsh Posté le 30-06-2006 à 09:01:06    

skelter a écrit :

parce-que un engin ne peut pas avoir de memoire flash qui fait office de ram ??


Non. Le cycle d'écriture dans la Flash est assez complexe (et son nombre est limité), ce qui interdit ce genre de pratique douteuse. Par contre, c'est OK pour sauvegarder des données non volatiles. (config, log, traces ...).
 
Sur les systèmes sans disque dur embarquant GNU/Linux, une partie de la Flash est en fait un 'disque Flash' qui contient la partie non volatile du FS (File System) indispensable au fonctionnement de tout Unixoïde...


Message édité par Emmanuel Delahaye le 30-06-2006 à 09:05:52

---------------
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 30-06-2006 à 09:03:23    

J'ai de la falsh (2mo) et de la ram (8mo).
 
Pour plus de détail sur mon module voir : http://www.digi.com/fr/products/em [...] nectme.jsp

Reply

Marsh Posté le 01-07-2006 à 06:00:28    

skelter a écrit :

parce-que un engin ne peut pas avoir de memoire flash qui fait office de ram ??


Non. D'ailleurs si tu faisais ça, ta Flash serait morte en quelques jours/heures.

Message cité 1 fois
Message édité par el muchacho le 01-07-2006 à 06:02:04

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 01-07-2006 à 06:12:48    

Vilo5 a écrit :

Ok.
 
Enfin bon je suppose que c'est ma pile qui explose, c'est peut être autre chose mais je ne vois pas quoi.
 
En tout cas sur ma machine de développement ca marche mais pas sur la cible.
Par contre si je fais un bête programme comme le suivant pour appeller mes fonctions post alors ca marche :
 
 
C''set donc bien en en reliant les fonctions post à mon prog principal (qui est bien plus gros que celui ci-dessus) que ca explose.
 
Biensure le prog principal fonctionne si je met en commentaire la ligne d'appel de la fonction post.


 
En tout cas, une fois que tu as fait ce que t'a dit Taz, ce =n'est plus ce code qui pose pb, c'est le reste (ton main), où tu as dû mettre qqs gros tableaux supplémentaires sur la pile. Si tu te définis comme règle empirique de tjrs faire un malloc au-delà de 128 octets (par ex.), tu ne devrais pas avoir trop de pb. Si 'as besoin de perfs dans une fonction appelée souvent et que tu ne veux pas faire de malloc/free répétés, alors tu crées un buffer de taille fixe sur lequel tu vas travailler et tu passes un pointeur à ta fonction dessus. Evidemment, il faudra un peu plus de rigueur sachant que le buffer n'est pas effacé à chaque utilisation.
cad au lieu de  

Code :
  1. void mon_traitement(){
  2.     char *buf = malloc (1024);
  3.     ... mon traitement ...
  4.     free(buf);
  5. }
  6. int main(){
  7.     for (int i = 0; i < 10000; i++) { mon_traitement(); }
  8. }


tu fais :

Code :
  1. void mon_traitement(char *buf){
  2.    ... mon traitement en faisant gaffe que buf est pas nettoyé...
  3. }
  4. int main(){
  5.     char *buf = malloc (1024);
  6.     for (int i = 0; i < 10000; i++) { mon_traitement(buf); }
  7.     free(buf);
  8. }


Conceptuellement, c'est moins joli, mais c'est de l'embarqué...

Message cité 1 fois
Message édité par el muchacho le 01-07-2006 à 06:25:20

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 01-07-2006 à 10:05:46    

el muchacho a écrit :

Non. D'ailleurs si tu faisais ça, ta Flash serait morte en quelques jours/heures.


+1, le nombre de lecture/écrite est limité.


---------------
Töp of the plöp
Reply

Marsh Posté le 01-07-2006 à 11:31:03    

el muchacho a écrit :

En tout cas, une fois que tu as fait ce que t'a dit Taz, ce =n'est plus ce code qui pose pb, c'est le reste (ton main), où tu as dû mettre qqs gros tableaux supplémentaires sur la pile. Si tu te définis comme règle empirique de tjrs faire un malloc au-delà de 128 octets (par ex.), tu ne devrais pas avoir trop de pb. Si 'as besoin de perfs dans une fonction appelée souvent et que tu ne veux pas faire de malloc/free répétés, alors tu crées un buffer de taille fixe sur lequel tu vas travailler et tu passes un pointeur à ta fonction dessus. Evidemment, il faudra un peu plus de rigueur sachant que le buffer n'est pas effacé à chaque utilisation.
cad au lieu de  

Code :
  1. void mon_traitement(){
  2.     char *buf = malloc (1024);
  3.     ... mon traitement ...
  4.     free(buf);
  5. }
  6. int main(){
  7.     for (int i = 0; i < 10000; i++) { mon_traitement(); }
  8. }


tu fais :

Code :
  1. void mon_traitement(char *buf){
  2.    ... mon traitement en faisant gaffe que buf est pas nettoyé...
  3. }
  4. int main(){
  5.     char *buf = malloc (1024);
  6.     for (int i = 0; i < 10000; i++) { mon_traitement(buf); }
  7.     free(buf);
  8. }


Conceptuellement, c'est moins joli, mais c'est de l'embarqué...


 
Ok c'est noté, merci !
 
Pour ce qui est de ce que taz a dit j'ai diminué la taille des tableaux qui était surdimensionné, j'ai déclaré en malloc et j'ai fais des free.
Mais par contre je n'ai pas pu le faire pour tous les tableaux.
 
En l'occurence pour :
    char head_buf[10000];
    char data_buf[50000];
    char enc_buf[5000];  
 
Si je le fait pour ces 3 tableaux mon code plante.
 
char* head_buf = (char*) malloc(500);
char* data_buf = (char*) malloc(500);
char* enc_buf= (char*) malloc(100);
 
Apparement en déclarant d ecette façon mon code n'est plus adapté.
 
Que faut t'il que je change d'autre ?

Reply

Marsh Posté le 01-07-2006 à 12:28:05    

ueh parce que 10000 != 500 peut-être ?

Reply

Marsh Posté le 02-07-2006 à 01:30:02    

Taz a écrit :

ueh parce que 10000 != 500 peut-être ?


 
Non non ca vient pas de là, la taille du tableau était réellement surdimensionné pour ce que j'en fait.
 
Avec "char data_buf[500];" ca marche, mais pas avec "char* data_buf = (char*) malloc(500);".

Reply

Marsh Posté le 02-07-2006 à 11:30:25    

et le retour de malloc :o

Reply

Marsh Posté le 03-07-2006 à 08:56:23    

Taz a écrit :

et le retour de malloc :o


 
Non pas de pb à ce niveau là.
 
Apparement ca viendrai plutôt de là :
 

Code :
  1. data_bytes += snprintf( &data_buf[data_bytes], sizeof(data_buf) - data_bytes, "&" );


 
Dns l'ancien code data_buf était un tableau et sizeof donnait la taille du tableau . Maintenant, data_buf est un pointeur et sizeof renvoie la taille du pointeur, pas la taille du tableau pointé!
 
Faut donc que je modifie çà je pense, mais comment ?

Reply

Marsh Posté le 03-07-2006 à 09:06:50    

Vilo5 a écrit :

Non pas de pb à ce niveau là.
 
Apparement ca viendrai plutôt de là :
 

Code :
  1. data_bytes += snprintf( &data_buf[data_bytes], sizeof(data_buf) - data_bytes, "&" );


 
Dns l'ancien code data_buf était un tableau et sizeof donnait la taille du tableau . Maintenant, data_buf est un pointeur et sizeof renvoie la taille du pointeur, pas la taille du tableau pointé!
 
Faut donc que je modifie çà je pense, mais comment ?


Je te conseille de conserver la taille (ou le nombre d'élements, c'est plus utile) et l'adresse du bloc alloué dans une structure :  

Code :
  1. struct bloc_dyn
  2. {
  3.    size_t n;
  4.    char *p;
  5. };


 

Code :
  1. struct bloc_dyn buf = {500, NULL};
  2. buf.p = (char*) malloc (buf.n * sizeof *buf.p);


Ensuite :  

Code :
  1. data_bytes += snprintf( buf.p + data_bytes, buf.n - data_bytes, "&" );


---------------
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 04-07-2006 à 08:47:00    

Emmanuel Delahaye a écrit :

Code :
  1. struct bloc_dyn
  2. {
  3.    size_t n;
  4.    char *p;
  5. };
  6. struct bloc_dyn buf = {500, NULL};
  7. buf.p = (char*) malloc (buf.n * sizeof *buf.p);



 
Ok merci, effectivement ca marche comme ca !
 
Mais j'aurai tout de même une question a ce sujet pour mieux comprendre.
 
Comment ca se passe la réservation mémoire dans ce cas ? (ligne par ligne)
 
Cette déclération réserve t'elle réellement moins de place en mémoire, comment ca se comporte et est-ce bien pour mon pb en embarqué.

Message cité 1 fois
Message édité par Vilo5 le 04-07-2006 à 08:48:03
Reply

Marsh Posté le 04-07-2006 à 10:08:24    

Vilo5 a écrit :

Ok merci, effectivement ca marche comme ca !
 
Mais j'aurai tout de même une question a ce sujet pour mieux comprendre.
 
Comment ca se passe la réservation mémoire dans ce cas ? (ligne par ligne)
 
Cette déclération réserve t'elle réellement moins de place en mémoire, comment ca se comporte et est-ce bien pour mon pb en embarqué.


C'est surtout que la mémoire n'est pas prise dans la pile, mais dans le tas. Si il n'y en a plus, tu es prévenu (NULL).
 
Evidemment, il faut libérer après usage.
 
(Pas trop vite, attention. L'émission se fait mode synchrone ou asynchrone)

Reply

Marsh Posté le 04-07-2006 à 13:36:49    

Emmanuel Delahaye a écrit :

C'est surtout que la mémoire n'est pas prise dans la pile, mais dans le tas. Si il n'y en a plus, tu es prévenu (NULL).
 
Evidemment, il faut libérer après usage.
 
(Pas trop vite, attention. L'émission se fait mode synchrone ou asynchrone)


 
 
Pourrait tu exactement m'expliquer la notion de pile et de tas, je pense que ca reste encore un peu plou dans mon esprit.
 
Je sais que que je charge mon system (busybox) compresser en .bin (environ 1.5Mo) grace a NFS dans mes 2 Mo de flash. Au boot du system  je suppose qu'il doit se décompresser dans mes 8Mo de ram. Après je suppose que quelque part dans la ram je doit avoir la pile pour mes applications, et le reste serait le tas. Ou rien à voir ?

Message cité 1 fois
Message édité par Vilo5 le 04-07-2006 à 13:37:45
Reply

Marsh Posté le 04-07-2006 à 13:56:46    

Vilo5 a écrit :

Pourrait tu exactement m'expliquer la notion de pile et de tas, je pense que ca reste encore un peu plou dans mon esprit.
 
Je sais que que je charge mon system (busybox) compresser en .bin (environ 1.5Mo) grace a NFS dans mes 2 Mo de flash. Au boot du system  je suppose qu'il doit se décompresser dans mes 8Mo de ram. Après je suppose que quelque part dans la ram je doit avoir la pile pour mes applications, et le reste serait le tas. Ou rien à voir ?


C'est à peu près çà, oui. Le tas, c'est la mémoire n'est occupée ni par le code, ni par les données (données statiques), ni par la pile (données automatiques). C'est dans cette zone que l'allocateur de mémoire dynamique vient reserver/libérer des blocs de données (malloc() / free()).

Message cité 1 fois
Message édité par Emmanuel Delahaye le 04-07-2006 à 13:59:04

---------------
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 04-07-2006 à 15:05:15    

Emmanuel Delahaye a écrit :

C'est à peu près çà, oui. Le tas, c'est la mémoire n'est occupée ni par le code, ni par les données (données statiques), ni par la pile (données automatiques). C'est dans cette zone que l'allocateur de mémoire dynamique vient reserver/libérer des blocs de données (malloc() / free()).


 
Ok !
 
Et la pile est bien dans la ram aussi ? Mais elle, elle prend une taille qui est réservé et situé a un endroit bien précis dans la ram. Et c'est cette taille qu'il ne faut pas dépasser sous risque de faire exploser la pile et avoir un programme qui se comporte n'importe comment et plante. Donc en règle général faut faire de mallocs et free au maximum car le tas est normalement plus grand que la pile, même dans l'embarqué.

Reply

Marsh Posté le 04-07-2006 à 15:10:33    

Bon alors voilà j'ai changé pas mal de chose dans le code, j'ai changé les déclaration pour mettre des mallocs suivi de free biensur, j'ai ajouté les structure que emmanuel ma conseillé et j'ai aussi ajouté du code pour récupérer juste les données que je souhaite et non tout le code XML provenant du serveur.
 
Voici mon nouveau fichier :
Nouveau fichier
 
J'ai mis en commentaire les lignes que j'ai changé (// en début de ligne qui se repère facilement), pourriez vous me dire si cela vous parrait correct et si j'ai bien fait des test correct sur mes mallocs et placé correctement mes free.
 
merci


Message édité par Vilo5 le 04-07-2006 à 15:15:47
Reply

Marsh Posté le 04-07-2006 à 16:51:41    

et le saint esprit l'a transformé en C++ ?

Reply

Marsh Posté le 04-07-2006 à 17:20:21    

Taz a écrit :

et le saint esprit l'a transformé en C++ ?


Ok ok mauvais rename lors du copier/coller, sorry !
 
Nouveau fichier


Message édité par Vilo5 le 04-07-2006 à 17:21:45
Reply

Marsh Posté le 04-07-2006 à 17:25:11    

1) t'as pas aimé ma remarque sur les const
2) je pense que les malloc n'ont servi à rien, c'était juste tes char[500000] qui foutaient la merde.

Reply

Marsh Posté le 04-07-2006 à 17:35:26    

Code :
  1. char* eq;
  2.    
  3.    
  4.      /* on s'en fout si l'écriture échoue, apres tout
  5.        (void) write( 1, data.data + i, data_bytes - i );
  6.        
  7.        
  8.        
  9.     /* eq != &eq[0] si si ça peut arriver. et puis ça peut se transformer en
  10.      méchant double* des fois.
  11.       Espérons quand même que eq point vers une zone d'au moins sizeof(eq).
  12.      T'aurais pas essayé de coder un truc obscure qui te donne l'impression
  13.      que eq == NULL alors qu'en fait tu ne mets à zéro que les {2,4,8}  
  14.     char qui suivent ? ça pue
  15. si ton programme plantait, c'est parce que tu devais sans doute écraser
  16. ta pile et peut peut etre pas tellement parce que tu lui en demandais
  17. beaucoup
  18.     */
  19.     memset((char *)&eq[0], 0, sizeof(eq));

Reply

Marsh Posté le 05-07-2006 à 08:59:22    

Taz a écrit :

1) t'as pas aimé ma remarque sur les const


 
Ok ok j'y penser plus à ça, donc toi tu veirrai bien ca :

Code :
  1. static const int b64_decode_table[256] = {
  2. static const char b64_encode_table[64] = {


Comme ca les tableaux ne seront plus dans la pile.
 
 

Taz a écrit :

2) je pense que les malloc n'ont servi à rien, c'était juste tes char[500000] qui foutaient la merde.


 
Bon ok de toute façon j'ai réduit les tableaux (ce que tu dit qui est bien) et en plus j'ai mis les malloc. Ca peut pas faire de mal d'avoir fait les 2 je pense, plutôt que du bien car je décharge tout de même un peu la pile comme çà. Car si ma pile et vraiment petite  (2 ou ko par exemple, j'attend une réponse d emon fournisseur pour être fixé), elle se rempira vite.


Message édité par Vilo5 le 05-07-2006 à 09:01:09
Reply

Marsh Posté le 05-07-2006 à 10:18:57    

Taz a écrit :

Code :
  1. char* eq;
  2.    
  3.    
  4.      /* on s'en fout si l'écriture échoue, apres tout
  5.        (void) write( 1, data.data + i, data_bytes - i );
  6.        
  7.        
  8.        
  9.     /* eq != &eq[0] si si ça peut arriver. et puis ça peut se transformer en
  10.      méchant double* des fois.
  11.       Espérons quand même que eq point vers une zone d'au moins sizeof(eq).
  12.      T'aurais pas essayé de coder un truc obscure qui te donne l'impression
  13.      que eq == NULL alors qu'en fait tu ne mets à zéro que les {2,4,8}  
  14.     char qui suivent ? ça pue
  15. si ton programme plantait, c'est parce que tu devais sans doute écraser
  16. ta pile et peut peut etre pas tellement parce que tu lui en demandais
  17. beaucoup
  18.     */
  19.     memset((char *)&eq[0], 0, sizeof(eq));



 
 
???????
 
Désolé, mais je n'ai pas tout compris ce que tu essaye de me dire là ?

Reply

Marsh Posté le 05-07-2006 à 10:47:32    

Ce qu'il veut dire c'est que ton code dénote une certaine méconnaissance du langage C, assez inquiétante étant donné ce que tu essaies de faire...
Dans l'ordre:


(void) write( 1, data.data + i, data_bytes - i );


Si tu ne vérifie pas la valeur de retour de write, comment peux-tu savoir que ça c'est bien passé, surtout que quand tu bosses avec des sockets, il est tout à fait possible qu'un seul appel ne suffise pas.
 
NEsuite,


&eq[0]


As-tu entendu parler d'une règle qui dit que dans une expression (à quelques exceptions près), un tableau est "considéré" (decay en anglais, je ne trouve pas l'équivalent en français) comme unpointeur vers son premier élément? Donc ton expression est strictement équivalente à 'eq'.
 
Enfin,


memset((char *)&eq[0], 0, sizeof(eq));  


Là c'est carrément louche.
 
En jettant un coup d'oeil à ton code, on voit que tu castes tes malloc() à chqaue fois, ensuite tu testes la valeur de retour.
Pourquoi ne pas factoriser le code en un xmalloc, histoire de gagner 50 lignes de codes.
En bref, si ton programme plante, c'est sûrement parce qu'il est mal codé.


Message édité par simple_stupid le 05-07-2006 à 10:48:03
Reply

Marsh Posté le 05-07-2006 à 11:09:02    

tu veux pas sortir un bouquin, lire wikipedia ou pire lire ce sujet en entier

Citation :

Comme ca les tableaux ne seront plus dans la pile.


 
je ne sais pas trop ce qu'on cherche en fait avec toi vu que tu ne sais pas ce qu'est la pile.

Reply

Marsh Posté le 05-07-2006 à 11:15:28    

[Hors Sujet]J'ai une question sur tes 'coding rules':  je trouve que les 'exit' dans des fonctions auxiliaires est une pratique très violente dans l'embarqué, ton main est mort sans savoir vraiment pourquoi... n'est-il pas plus judicieux de retourner une valeur signifiant 'error' pour que le main puisse retomber sur ces pieds? De plus, avant les 'exit' dans les cas de mauvais malloc, tu ne libère pas la mémoire précedement allouée...
Globalement, ton code me fait peur

Reply

Marsh Posté le 05-07-2006 à 11:16:13    

Bon ok,
 
alors de toute façon les lignes suivantes :
 

Code :
  1. (void) write( 1, data.data + i, data_bytes - i );
  2.  
  3.    /* Copy the data. */
  4.     for (;;)
  5.    {
  6. data_bytes = read( sockfd, data.data, data.size);
  7. if ( data_bytes == 0 )
  8.     break;
  9. if ( data_bytes < 0 )
  10.     show_error( "read" );
  11.         (void) write( 1, data.data, data_bytes );
  12.      }


 
Puisque tout ce que je veux c'est récupérer "data.data" qui est ma réponse XML, afin de la traiter (enlever les balises XML pour récupérer juste le nom et le solde)

Reply

Marsh Posté le 05-07-2006 à 13:24:33    

western a écrit :

[Hors Sujet]J'ai une question sur tes 'coding rules':  je trouve que les 'exit' dans des fonctions auxiliaires est une pratique très violente dans l'embarqué, ton main est mort sans savoir vraiment pourquoi... n'est-il pas plus judicieux de retourner une valeur signifiant 'error' pour que le main puisse retomber sur ces pieds? De plus, avant les 'exit' dans les cas de mauvais malloc, tu ne libère pas la mémoire précedement allouée...
Globalement, ton code me fait peur


 
Oui c'est vrai c'est a modifier aussi, il faudra que je regarde ca aussi après, mais la pour le moment je m'acharne à esayer de la faire tourner sur ma platform embarqué. mais ce n'est pas a négliger je suis d'accord faudra que je traite çà.
 
En fait le pb principal, vous vous en douté, c'est que à la base ce n'est pas un programme codé pour de l'embarqué. Ca se voit d'ailleurs !


Message édité par Vilo5 le 05-07-2006 à 13:26:08
Reply

Marsh Posté le 05-07-2006 à 14:23:10    

Je ne vois pas ce que tu peux de faire plus dans ce fichier (à part faire des write directe au lieu de sprintf et concatenation) mais tu risque de sérieusement dégradé les performances
 
question: Que fait le main? Combien de RAM utilise-t-il? Peux-tu l'optimiser? Tu peux utiliser des outils comme gprof et gcov et biensur gdb/ddd pour regarder la mémoire, les appels aux fonctions, etc.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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