Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1456 connectés 

  FORUM HardWare.fr
  Programmation
  C

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

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

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

n°1396742
Vilo5
Posté le 28-06-2006 à 17:32:55  profilanswer
 

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
mood
Publicité
Posté le 28-06-2006 à 17:32:55  profilanswer
 

n°1396816
Taz
bisounours-codeur
Posté le 28-06-2006 à 19:26:55  profilanswer
 

   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
 

n°1396817
Taz
bisounours-codeur
Posté le 28-06-2006 à 19:30:14  profilanswer
 

t'as pas de main au fait ...

n°1397258
Vilo5
Posté le 29-06-2006 à 15:34:25  profilanswer
 

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.

n°1397264
_darkalt3_
Proctopathe
Posté le 29-06-2006 à 15:42:33  profilanswer
 

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
n°1397286
skelter
Posté le 29-06-2006 à 16:15:26  profilanswer
 

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

n°1397293
_darkalt3_
Proctopathe
Posté le 29-06-2006 à 16:21:43  profilanswer
 

ah oui zut j'avais pas vu.

n°1397316
Vilo5
Posté le 29-06-2006 à 16:48:21  profilanswer
 

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
n°1397437
skelter
Posté le 29-06-2006 à 20:06:42  profilanswer
 

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
n°1397525
Emmanuel D​elahaye
C is a sharp tool
Posté le 29-06-2006 à 22:47:05  profilanswer
 

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/
mood
Publicité
Posté le 29-06-2006 à 22:47:05  profilanswer
 

n°1397572
skelter
Posté le 30-06-2006 à 00:16:04  profilanswer
 

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 ??

n°1397678
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-06-2006 à 09:01:06  profilanswer
 

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/
n°1397679
Vilo5
Posté le 30-06-2006 à 09:03:23  profilanswer
 

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

n°1398423
el muchach​o
Comfortably Numb
Posté le 01-07-2006 à 06:00:28  profilanswer
 

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
n°1398425
el muchach​o
Comfortably Numb
Posté le 01-07-2006 à 06:12:48  profilanswer
 

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
n°1398449
_darkalt3_
Proctopathe
Posté le 01-07-2006 à 10:05:46  profilanswer
 

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
n°1398467
Vilo5
Posté le 01-07-2006 à 11:31:03  profilanswer
 

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 ?

n°1398496
Taz
bisounours-codeur
Posté le 01-07-2006 à 12:28:05  profilanswer
 

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

n°1398723
Vilo5
Posté le 02-07-2006 à 01:30:02  profilanswer
 

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);".

n°1398756
Taz
bisounours-codeur
Posté le 02-07-2006 à 11:30:25  profilanswer
 

et le retour de malloc :o

n°1399138
Vilo5
Posté le 03-07-2006 à 08:56:23  profilanswer
 

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 ?

n°1399145
Emmanuel D​elahaye
C is a sharp tool
Posté le 03-07-2006 à 09:06:50  profilanswer
 

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/
n°1399952
Vilo5
Posté le 04-07-2006 à 08:47:00  profilanswer
 

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
n°1399985
Emmanuel D​elahaye
C is a sharp tool
Posté le 04-07-2006 à 10:08:24  profilanswer
 

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)

n°1400185
Vilo5
Posté le 04-07-2006 à 13:36:49  profilanswer
 

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
n°1400214
Emmanuel D​elahaye
C is a sharp tool
Posté le 04-07-2006 à 13:56:46  profilanswer
 

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/
n°1400329
Vilo5
Posté le 04-07-2006 à 15:05:15  profilanswer
 

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é.

n°1400333
Vilo5
Posté le 04-07-2006 à 15:10:33  profilanswer
 

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
n°1400478
Taz
bisounours-codeur
Posté le 04-07-2006 à 16:51:41  profilanswer
 

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

n°1400532
Vilo5
Posté le 04-07-2006 à 17:20:21  profilanswer
 

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
n°1400541
Taz
bisounours-codeur
Posté le 04-07-2006 à 17:25:11  profilanswer
 

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.

n°1400562
Taz
bisounours-codeur
Posté le 04-07-2006 à 17:35:26  profilanswer
 

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));

n°1400837
Vilo5
Posté le 05-07-2006 à 08:59:22  profilanswer
 

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
n°1400886
Vilo5
Posté le 05-07-2006 à 10:18:57  profilanswer
 

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à ?

n°1400907
simple_stu​pid
Keep It Simple Stupid
Posté le 05-07-2006 à 10:47:32  profilanswer
 

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
n°1400931
Taz
bisounours-codeur
Posté le 05-07-2006 à 11:09:02  profilanswer
 

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.

n°1400935
western
AJMM
Posté le 05-07-2006 à 11:15:28  profilanswer
 

[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

n°1400936
Vilo5
Posté le 05-07-2006 à 11:16:13  profilanswer
 

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)

n°1401067
Vilo5
Posté le 05-07-2006 à 13:24:33  profilanswer
 

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
n°1401119
western
AJMM
Posté le 05-07-2006 à 14:23:10  profilanswer
 

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.

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

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

 

Sujets relatifs
donner un numero de version automatique au programmePetit programme de débutant
besoin d'un programme pour exécuter un fichier[php] programme de droit avec un type=file
Faire un programme de teste de carte mémoireexecution programme python
Macro ProgramméInterface graphique programme en SDL ???
Lost connection to MySQL server during query -> Comment eviter cela ?Logiciel de tests d un programme
Plus de sujets relatifs à : Alléger un programme pour éviter de faire exploser la pile.


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR