1

Voilà, je suis entrain de faire un programme qui interprète un pseudo language d'un fichier TEXT pour pouvoir faire des textes en niveau de gris et des pages "dynamiques" mais j'ai pas mal de problèmes avec les tableaux.
Je me suis rendu compte que déclaré à certains endroits, il y a pas mal de problèmes. Alors j'ai décidé de les allouer mais finalment j'en ai toujours autant.

typedef struct
{
unsigned char return_line:1;
unsigned char stick_char:1;
unsigned char color:2;
unsigned char center:1;
unsigned char under_line:1;
}Str_Mode;

typedef struct
{
char chaine[80];
Str_Mode param;
}Text;

Text *TEXT;
TEXT=malloc(sizeof(Text)*100);

Alors déjà, même si la chaîne fait 10 de long il y a des problème si la taille de chaine est inférieur à 80... je ne sais pas trop pourquoi mais bon ?!
Ensuite si la valeur ici : TEXT=malloc(sizeof(Text)*100); est inférieur à 100, c'est pareil j'ai des problèmes, même si j'ai trois chaine stockées.
Ca se traduit par du texte d'un autre fichier qui vient de mettre dedans ou alors des paramètres qui ne marchent pas...enfin c'est très capricieux.

Par contre je ne sais pas où vontchar chaine[80]; lorsque je fais ça TEXT=malloc(sizeof(Text)*100); ? C'est sur le stack, ou c'est alloué ?
Et en faisant comme cela : TEXT=malloc(sizeof(Text)*100);, ça alloue bien un tableau de 100 ?
En fait ce que ej veux faire c'est pour chaque éléments de TEXT (TEXT[0], TEXT[1], ...) c'est d'avoir une chaine de taille assez grande mais pas forcément déterminé à l'avance et un paramètre.
Et là je ne suis pas sûr de ce que je fais vu le nombre de problèmes créer à causes de ces tableaux.
www.wikio.fr/user1921&info=comments

2

Raphaël :
Par contre je ne sais pas où vontchar chaine[80]; lorsque je fais ça TEXT=malloc(sizeof(Text)*100); ? C'est sur le stack, ou c'est alloué ?
Un malloc alloue l'espace en RAM.
Et en faisant comme cela : TEXT=malloc(sizeof(Text)*100);
, ça alloue bien un tableau de 100 ?
100 éléments de 81 octets, soit 8100 octets.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

3

Ouais mais comme la chaîne fait 80 octets, il y a peut-être des problèmes lorsqu'elle en fait moins.
www.wikio.fr/user1921&info=comments

4

Bah de toute façon, tu auras au moins 80 octets alloués, donc s'il peut y avoir des pb, c'est si la chaine fait plus.
Je pense que tu n'as pas bien compris.
Poste ton code.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

5

// C Source File // Created 09/08/2003; 10:10:05 #define USE_TI89              // Compile for TI-89 #define OPTIMIZE_ROM_CALLS    // Use ROM Call Optimization #define MIN_AMS 100           // Compile for AMS 1.00 or higher #define SAVE_SCREEN           // Save/Restore LCD Contents        // Include All Header Files ///#include "Text_Liver.h" #include "Extgraph.h" #include <tigcclib.h>  #include "Extgraph_asm_routines.h" #include "TinyX.h" #define Draw_into_LIGHT_BUFFER() PortSet(Light_Buffer,239,127); #define Draw_into_DARK_BUFFER()  PortSet(Dark_Buffer,239,127); #define GetKey() (kbhit() ? ngetchx() : 0) void *Light_Buffer; void *Dark_Buffer; typedef struct {      unsigned char return_at_line:1;      unsigned char stick_char:1;      unsigned char color:2;      unsigned char center:1;      unsigned char under_line:1; }Str_Mode; typedef struct {      char chaine[100];      Str_Mode param; }Text; void LLGKenter(void) {       int i =0;       for(i=0;i<10;i++)            {                 cos(cos(cos(i)));            }      do{                                 }while(!(_keytest(RR_ESC))); } inline int FindNextChar(unsigned char Char,unsigned int current_position,unsigned char *buffer) {      unsigned int len=strlen(buffer);      while(buffer[current_position]!=Char && current_position<len)      {           current_position++;   };   if(current_position<len)   {     return current_position;   }else      {                      return -1;      }             } void Draw_GrayStr(int x, int y,const char *str,Str_Mode mode) {            register unsigned int i;      int y_font_size=0, x_font_size=0;            void return_to_line(void)      {           if(!mode.return_at_line)           return;           if(x>(160-(2*x_font_size+x_font_size/2))) // si x est supérieur aux nombre de caractère écrit multiplié par la taille de la police           {                x=-x_font_size; // Retour à la ligne en x                y=y+y_font_size; // passe à la ligne d'en dessous.           }      }            switch(tX_GetFont())      {           case tF_4x6:           x_font_size=4 - mode.stick_char;           y_font_size=6;           break;           case tF_6x8:           x_font_size=6 - mode.stick_char;           y_font_size=8;           break;           case tF_8x10:           x_font_size=8 - mode.stick_char;           y_font_size=10;           break;      }      void under_line(void) // MODE SOULIGNE      {           if(!mode.under_line) // si le mode n'est pas souligné           return; // retourne           FastDrawHLine_faster_stkparm(Light_Buffer,x,x-strlen(str)*x_font_size,y+y_font_size,A_NORMAL); // sinon dessine une ligne en dessous de la chaîne en commençant par la fin      }                 switch(mode.color)           {                case 0:                    for(i=0;i<strlen(str);i++) // Pour chaque caractère de la chaîne              {                        tX_DrawChar(x,y,str[i],Light_Buffer);                        return_to_line();                        x=x+x_font_size; // ajoute la taille d'un caractère à x afin de pouvoir dessiner le caractère suivant                    }                under_line();                break;                                case 1:                            for(i=0;i<strlen(str);i++) // Pour chaque caractère de la chaîne              {                        tX_DrawChar(x,y,str[i],Dark_Buffer);                        return_to_line();                        x=x+x_font_size; // ajoute la taille d'un caractère à x afin de pouvoir dessiner le caractère suivant                    }                under_line();                break;                                case 2:                              for(i=0;i<strlen(str);i++) // Pour chaque caractère de la chaîne              {                             tX_DrawChar(x,y,str[i],Light_Buffer);                          tX_DrawChar(x,y,str[i],Dark_Buffer);                          return_to_line();                          x=x+x_font_size; // ajoute la taille d'un caractère à x afin de pouvoir dessiner le caractère suivant                    }                           under_line();                break;                                case 3:                                 for(i=0;i<strlen(str);i++) // Pour chaque caractère de la chaîne              {                        tX_DrawChar(x,y,str[i],Light_Buffer);                        tX_DrawChar(x,y,str[i],Dark_Buffer);                        return_to_line();                        x=x+x_font_size; // ajoute la taille d'un caractère à x afin de pouvoir dessiner le caractère suivant                    }       under_line();                break;            }                        } int Menu_Popup(char *Menu_Elem[],int nb_elem,const char *Title) {      #define font_offset 1      Str_Mode mode={0,0,1,0,1};      int y_font_size=0, x_font_size=0;      int center_x=0,center_y=0,i=0,top_title = 0;      unsigned int max_elem_lenght=0;            for(i=0;i!=nb_elem;i++) // determine l'élement le plus long du menu afin de connaître sa taille      {              if(strlen(Menu_Elem[i])>max_elem_lenght)              {                     max_elem_lenght=strlen(Menu_Elem[i]);              }      }      if(strlen(Title)>max_elem_lenght) // sans oublier le titre      {             max_elem_lenght = strlen(Title);       }            switch(tX_GetFont())      {           case tF_4x6:           x_font_size=4;           y_font_size=8;                      break;           case tF_6x8:           x_font_size=6;           y_font_size=10;                 break;           case tF_8x10:           x_font_size=8;           y_font_size=12;                      break;      }      int x = ((x_font_size/2) * (max_elem_lenght+1)); // calcule la moitié longeur x de la fenêtre d'après la taille de la font et la taille du plus grand élément      int y = ((y_font_size/2) * 5) + 2;        int xmin = 80 - x - x_font_size ; // xmin, xmax, ymin, ymax sont les coordonnées du cadre des elements.      int xmax = 80 + x - x_font_size;      int ymin = 50 - y + y_font_size/2+1;      int ymax = 50 + y + x_font_size/2+1;            do      {           center_y = 50-(y_font_size/2*5)+ y_font_size/2+1; // moitié de l'écran en y = 50 - moitié de la longeur de la font = 3 -(moitié de l'espace en x entre chaque titre * 5)        memset(Light_Buffer,0,3000); // Efface le plan caché        memset(Dark_Buffer,0,3000);                              FastLine(xmin,ymin,xmax+2*x_font_size,ymin,Dark_Buffer); // ligne horizontale du haut        FastLine(xmin,ymax,xmax+2*x_font_size,ymax,Dark_Buffer); // ligne horizontale du bas        FastLine(xmin,ymin-y_font_size-2,xmin,ymax,Dark_Buffer);  // ligne de gauche        FastLine(xmax,ymin-y_font_size-2,xmax,ymax,Dark_Buffer); // ligne de droite        FastLine(xmax+2*x_font_size,ymin-y_font_size-2,xmax+2*x_font_size,ymax,Dark_Buffer); // ligne de droite = de la barre        FastLine(xmin,ymin-y_font_size-2,xmax+2*x_font_size,ymin-y_font_size-2,Dark_Buffer); // ligne horizontale au dessus du titre       // FastLine(0,50,160,50,Dark_Buffer);        for(i=xmax+1;i<xmax+2*x_font_size-1;i++) // rempli la barre gris droite en light gray // modif -1        {             FastLine(i,ymin+1,i,ymax-2,Light_Buffer);  // -2 = -1        }                for(i=top_title;i<top_title+5;i++) // affiche cinq titre ou moins suivant la postion de top_title        {               if(i<nb_elem) // teste pour ne pas afficher les titre s'il y en a moins de 5 dans la fenêtre               {                     center_x = 80 - strlen(Menu_Elem[i])*(x_font_size/2) - x_font_size; // permet de center la chaîne en x = 160/2 - longeur de la font/2 = 77 - longeur de la chaîne moins longeur de la font/2                                          if(i==top_title) // si le titre correspond à celui du sommet                     {                               Draw_GrayStr(center_x,center_y+font_offset,Menu_Elem[i],mode); // dark                               int i_;                               for(i_=center_y;i_<center_y+y_font_size;i_++)                               {                                                                          FastDrawHLine(Dark_Buffer,xmin+2,xmax-2,i_,A_XOR);                                   FastDrawHLine(Light_Buffer,xmin+2,xmax-2,i_,A_XOR);                               }                                                                                                                          }else                     {                              Draw_GrayStr(center_x,center_y+font_offset,Menu_Elem[i],mode); // light gray                                                   }                                          center_y=center_y+y_font_size; // passe à la ligne suivante                              }           } //============================ Affiche le titre =====================================================                     int title_center_x = 80 - strlen(Title)*(x_font_size/2)- x_font_size;           Draw_GrayStr(title_center_x,ymin-y_font_size+1,Title,mode); // dark //===================================================================================================                                 memcpy(GetPlane(0),Light_Buffer,3000);     memcpy(GetPlane(1),Dark_Buffer,3000);            if(_keytest(RR_UP) && top_title!=0) // Pour ne pas que le top_title soit un titre qui se situe avant le première éléments de la liste.     {          top_title--;     }     if(_keytest(RR_DOWN) && top_title+1<nb_elem) // Pour ne pas que le top_title soit un titre qui se situe après le dernier de la liste     {          top_title++;     }               }while(!_keytest(RR_ENTER));               return top_title; // retourne le nombre correspondant à l'élément du menu choisi } void *Load_Taged_File(const char *Tag) {         short File_BOOL=0;         void *Buffer_File=NULL;         FILE *Current_File; // déclare lr pointeur vers le fichier         SYM_ENTRY * SYM_Ptr; // créer un pointeur SYM_Ptr         char *List_Files[40]; // créer une liste qui contiendra les noms des fichiers du répertoire.         char TAG_File[10]; // Chaîne de caractère qui servira à stocker le Tag avec fread();         int File_num=-1;                           SYM_Ptr = SymFindFirst (SYMSTR ("main"),FO_SINGLE_FOLDER); // Cherche les noms des fichiers du répertoire.                       while(SYM_Ptr) // tant que tout le répertoire n'est pas parcouru (et qu'il y a au moins un fichier)         {                                                char *File_name = SYM_Ptr->name;                  if((Current_File = fopen(File_name,"r"))) // Ouvre le fichier courant                  {                            // Si l'ouverture du fichier a réussi//                                                                                                       fgets(TAG_File,strlen(Tag)+1,Current_File);                         fclose(Current_File); // Fermeture du fichier                                                                                                                            if(!strcmp(TAG_File,Tag)) //quand la fonction qui permet de comparer deux chaînes de caractères retourne 0                     {                                File_num++; // Incrémente la variable pour situer le numéro du fichier danns la liste.                                List_Files[File_num] = File_name; // copie le nom du fichier dans la liste.                                                 }                                      }                                   SYM_Ptr=SymFindNext(); // Passe au fichier suivant.                                                                                                                            //printf("Fichier : %s, Tag : /%s/\n",SYM_Ptr->name,TAG_File);                                      } // Fin de la boucle qui parcoure le répertoire.                           tX_SetFont(tF_6x8);                                         if(File_num>-1) // Si au moins un fichier ayant le Tag des fichier TL.         {                                                File_num=Menu_Popup(List_Files,File_num+1,"Selectionner un fichier"); // Menu perso en grayscale / renvoi le numéro correpondant                                            if(File_num>-1) // Protection pour ne pas qu'il y est de plantage lorsque l'on appuye sur ESC par exemple               {                                                           if((Current_File=fopen(List_Files[File_num],"r"))) // Ouvre le fichier en mode binaire afin de le lire                    {                             // Si l'ouverture réussi //                          //printf_xy(0,70,"ouverture du fichier réussi !");                          unsigned long File_Size=0;                          fseek(Current_File,0,SEEK_END); // Positionne le curseur à la fin du fichier.                          File_Size=ftell(Current_File);  // Détermine la taille du fichier grâce à la position de la lecture                          fseek(Current_File,0,SEEK_SET); // Repositionne la lecture en début de fichier.                                                    if((Buffer_File=malloc(File_Size))) // Si l'allocation de mémoire réussi                          {                                                                      File_BOOL=1; // Afin de savoir qu'un fichier à été charger et qu'il faut libérer le bloc de mémoire alloué à la fin !                                   //printf_xy(0,78,"Allocation du fichier réussi !");                                if(fread(Buffer_File,File_Size,1,Current_File)) // Copie le Fichier dans un Buffer.                                {                                                                              //printf_xy(0,84,"Lecture du fichier réussi !");                                       //printf("Vrai File size du fichier : %lu",sizeof(Current_File));                                    //printf("File lenght : %lu",strlen(Buffer_File));                                    //printf("File size: %lu",File_Size);                                    //LLGKenter();                                    //ClrScr();                                    //printf("Vrai File size: %lu",sizeof(Buffer_File));                                };                                                                ///DrawGrayStr(0,0,Buffer_File,1);                                   //printf("Buffer File test 1  = %lu", strlen(Buffer_File));                                   //ngetchx();                                                                                          }                                                    fclose(Current_File);                                                                        }                           }                               }                       if(File_BOOL==1)      {        return Buffer_File;      }else      {           printf("NULL !");           LLGKenter();           return NULL;      }             } // Fin de la Fonction Load_TLF() // Main Function void _main(void) { /*============================= Initialisation ============================================================*/      //clrscr(); // efface l'écran      INT_HANDLER save_int_1;      save_int_1=GetIntVec(AUTO_INT_1); // sauvegarde l'auto int 1      SetIntVec(AUTO_INT_1,DUMMY_HANDLER); // détourne l'auto int 1      tX_LoadFont();      GrayOn(); // Active les niveaux de gris /*===========================================================================================================*/                Light_Buffer=malloc(3840);       Dark_Buffer = malloc(3840);            char *Buffer_File=Load_Taged_File("#TL TAG"); // charge un fichier TL et return l'adresse du buffer alloué       memset(Light_Buffer,0,3840); // efface le plan clair (caché)       memset(Dark_Buffer,0,3840);  // efface le plan foncé (caché)              Str_Mode mode={1,0,1,0,0};                            unsigned int curs_pos = 8;       int begin_str; int end_str;       int n;       Text *TEXT;       TEXT=malloc(sizeof(Text)*100);       char *current_param=malloc(2*sizeof(char));       int param_pos=0,str_pos;       int begin_param;       int nb_str=0;       tX_SetFont(tF_4x6);       int max=0;       while(curs_pos+3<strlen(Buffer_File))       {                  curs_pos++;                                    if(Buffer_File[curs_pos]=='"') // si la position du curseur est sur un "                  {                            str_pos=0;                            begin_str=curs_pos+1; // détermine le début de la chaine                            end_str=FindNextChar('"',begin_str,Buffer_File)-1; //détermine la in de la chaîne                                                        for(n=begin_str;n!=end_str+1;n++) // on part du debut de la chaine et on la copie jusqu'a la fin                            {                                     TEXT[nb_str].chaine[str_pos]=Buffer_File[n];                                     str_pos++;                            }                            if(str_pos>max)                            max=str_pos;                            curs_pos=end_str+2; // place le curseur juste après le " qui est souvent un = d'ailleurs                                                                                  if(Buffer_File[curs_pos]=='=' && Buffer_File[curs_pos+1]== '{') // si des paramètres sont associé au texte                           {                                     begin_param = curs_pos +2; // on place begin_param juste après {                                     n = begin_param;                                     param_pos=0;                                                                                                                                                                                                                          do{ // extrait tout les paramètres entre { }                                                                                                                                                   current_param[0]=Buffer_File[n];                                              current_param[1]=Buffer_File[n+1];                                                                                                                                              if(!(strcmp(current_param,"tc")))                                                 {                                                      TEXT[nb_str].param.center = 0;                                                 }                                                 if(!(strcmp(current_param,"sc")))                                                 {                                                      TEXT[nb_str].param.stick_char = 1;                                                                                                                                                             }                                                 if(!(strcmp(current_param,"c0")))                                                 {                                                      TEXT[nb_str].param.color = 0;                                                                                                       }                                                 if(!(strcmp(current_param,"c1")))                                                 {                                                      TEXT[nb_str].param.color = 1;                                                                                                                                                        }                                                 if(!(strcmp(current_param,"c2")))                                                 {                                                      TEXT[nb_str].param.color = 2;                                                 }                                                 if(!(strcmp(current_param,"c3")))                                                 {                                                      TEXT[nb_str].param.color = 3;                                                 }                                                  if(!(strcmp(current_param,"ts")))                                                 {                                                      TEXT[nb_str].param.under_line = 1;                                                 }                                                                                                                                                   //printf_xy(50,50,"%s",current_param);                                                 //int st=strcmp(current_param,"c0");                                                // printf_xy(50,60,"%i",st);                                                 //printf_xy(50,50,"%d",(int)strlen(current_param));                                                 //LLGKenter();                                                 n=n+3;                                                                                                                                       }while(Buffer_File[n-1] != '}');                                                                                                     curs_pos = n; // juste après } normalement                                                                                    }                nb_str++;                }      };                                   printf("%d",max);      LLGKenter();                                                                                                       if(Buffer_File)       {                   do          {                   int i;                   for(i=0;i<nb_str;i++)                   {                        mode=TEXT[i].param;                        TEXT[i].param.return_at_line=1;                        Draw_GrayStr(0,8*i+8,TEXT[i].chaine,mode);                   }                         memcpy(GetPlane(0),Light_Buffer,3840);                memcpy(GetPlane(1),Dark_Buffer,3840);                  }while(!_keytest(RR_ESC));                     }                                 if(Buffer_File)// si un fichier à été chargé, libère la mémoire allouée       {              free(Buffer_File);       }        free(current_param);       free(TEXT);       tX_FreeFont();       free(Light_Buffer);       free(Dark_Buffer);       GrayOff(); // désactive les niveaux de gris       SetIntVec (AUTO_INT_1, save_int_1); // restsaure l'auto int 1        }

Non et puis en plus la chaîne maximum dans le fichier test faisait 24 de long.
Maintenant ça à planté, donc j'ai plus rien. sad
Sinon c'est qu'il y a un problème autre part...
www.wikio.fr/user1921&info=comments

6

Au lieu de faire :
Text *TEXT;
TEXT=malloc(sizeof(Text)*100);

fait:

Text TEXT[100];
Je sais pas si ça change grand chose ... mais, essaye tout de même
http://membres.lycos.fr/pingooz/
Un cafe et deux sucres

7

Ouais je vais essayer mais c'est ce que je faisais avant.
www.wikio.fr/user1921&info=comments

8

Ca plante ! sad Avec 20 ça passe par contre. Mais bon je ne vais pas limiter mon "reader" de texte à 20 ligne !
Pourtant je croyais qu'il y avais 16 ko sur le stack. C'est pas avec ce tabeau que je le rempli pourtant ?
Dans ce programme j'ai que des problèmes avec les tableaux, je ne comprends pas trop pourquoi ?
Il y a peut-être un truc qui est différents : j'utilise TinyX pour les fonts et il faut les charger en début de programme... je ne sais pas si ça peut venir de ça ?

Et puis quand je retire des caractère dans une chaîne du fichier texte, le programme affiche quand même la chaine telle qu'elle était avant ! par contre si j'en rajoute, ils sont bien pris en compte !
Ca veut dire que le tableau garde en mémoire les chaînes. C'est un peu bizarre !
www.wikio.fr/user1921&info=comments

9

Ce n'est pas impossible que ça plante si tu essaies d'allouer sur la pile : ton tableau fait 100*(100+1) octets, soit 10100 octets. Si on rajoute l'écran à sauver à cause du SAVE_SCREEN,, on est déjà à 13940, on est assez proches de la limite autorisée...

Au fait, tu ne vérifies jamais le succès de tes mallocs, tu devrais le faire. Vu la quantité de RAM que tu demandes, ça peut peut-être venir de là, tes pb.

Sinon pourquoi tu alloues un bloc de 2 octets ? (char *current_param=malloc(2*sizeof(char));)
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

10

Ouais, c'est même exactement ça ! je suis obligé de faire un memset à chaque fois pour effacer le tableau Text TEXT[20]; ... c'est normal ? Normalment il faut mettre static pour que ça reste, non ?
www.wikio.fr/user1921&info=comments

11

Sinon pourquoi tu alloues un bloc de 2 octets ? (char *current_param=malloc(2*sizeof(char))wink

Ah, bien vu ! Alors déjà c'est parce-que j'avais des problème quand je n'allouais pas de mémoire et en plus à ce qui paraît ça bouffe moins de pile.
www.wikio.fr/user1921&info=comments

12

Au fait, tu ne vérifies jamais le succès de tes mallocs

Ouais mais je le fais toujours par la suite. Là j'ai 162 ko donc je sais que j'ai la place. Mais c'est clair que si un jour je diffuse ce programme je le ferais.
Par contre c'est vrai que ça prend pas mal de mémoire et je ne pensais même pas au SAVE_SCREEN
www.wikio.fr/user1921&info=comments

13

Ce que je ne comprends pas non plus c'est pourquoi en dessous de 80 (pour les chaine) il y a aussi des problème.
www.wikio.fr/user1921&info=comments