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

  FORUM HardWare.fr
  Programmation
  C

  [C] Pourquoi cette perte de mémoire?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Pourquoi cette perte de mémoire?

n°659967
avander
Posté le 01-03-2004 à 12:24:31  profilanswer
 

Bonjour à tous,
 
Je fait de la maintenance sur un programme C développé en Borland 3.1 sous DOS et je ne m'explique pas le phénomène suivant :  
 
une fonction lis un fichier texte qui contient des paires de noms -prénoms et alloue de l'espace mémoire dynamiquement. Chaque nom et prénom dans le fichier est composé de 22 caractères ( histoire de tester la capacité maximum de l'application), je m'attend donc qu'à chaque fois  la mémoire disponible diminue de ( 22 + 1) x 2 = 46 bytes or la différence entre un coreleft() avant et après l'allocation est de 64 unités... soit une différence de 18 bytes!
 
La fonction d'allocation actuelle :

Code :
  1. char* Alloc_String( char* String)
  2. {
  3.    char* Destination = new char [ strlen( String) + 1];
  4.    if ( Destination == NULL)
  5.    {
  6.       #if _DEBUGMODE
  7.          sprintf( gcDcio, "!!! Can't create new !!! String[%d] cleft[%lu]",
  8.             strlen( String) + 1, coreleft()); dcio();
  9.       #endif // _DEBUGMODE
  10.       Error_Exit( E_OUT_OF_MEMORY);
  11.    }
  12.    return strcpy( Destination, String);
  13. }


 
Ou est passé la différence? Est-il possible de l'éviter par exemple avec malloc()?


Message édité par avander le 01-03-2004 à 12:25:15
mood
Publicité
Posté le 01-03-2004 à 12:24:31  profilanswer
 

n°659972
Taz
bisounours-codeur
Posté le 01-03-2004 à 12:30:33  profilanswer
 

euh c'est un plaisanterie ?
 
le new là, c'est pour me faire un blague ?
 
 
mon remplace ton new par un malloc(strlen(String)+1);
 
et le pointeur que tu récupère comme ça
 
char *str = Alloc_String("dawa" );
 
oublie pas de faire un petit free dessus
 
free(str); en fin de programme
 
 
bingo, tu viens de réécrire la célèbre strdup
 
personnellement, j'aurais mémorié strlen pour faire un memcpy plutot qu'un strcpy

n°659977
avander
Posté le 01-03-2004 à 12:38:30  profilanswer
 

Merci Taz,  
 
Désolé j'hérite de cette 'application', beaucoup de monde est déjà passé par là...  
 
Je me demandais aussi pourquoi un new ici et pas un malloc tout simplement ( pourquoi faire facile si on peut faire compliqué ;-), est-ce que la différence peut venir de là?  
 
Toutefaçon, je vais tester les différentes solutions y compris strdup() !

n°659980
Taz
bisounours-codeur
Posté le 01-03-2004 à 12:40:35  profilanswer
 

new c'est du C++
 
moi je l'aurais écrite comme ça
 

Code :
  1. char *str_dup(const char *s)
  2. {
  3.   size_t len = strlen(s)+1;
  4.   char *new = malloc(len);
  5.   if(!new)
  6.     {
  7.       perror("malloc" );
  8.       /* peut-être un exit() ici */
  9.       return NULL;
  10.     }
  11.  
  12.   memcpy(new, s, len);
  13.   return new;
  14. }


 
strdup n'est pas forcément fournit par ton système en fait, mais regarde, ya sans doute des choses semblables

n°659987
avander
Posté le 01-03-2004 à 12:47:18  profilanswer
 

si si strdup() est dispo, comprend pas pourquoi on réinvente la roue ici :-((
 
merci pour le ( joli) code. A+

n°660169
avander
Posté le 01-03-2004 à 16:50:37  profilanswer
 

Après investigation un début de réponse, l'usage de new en non malloc ne semble pas être en cause.  
 
Lorsqu'on alloue un string d'un caractère on note que d'office on perd 16 bytes de mémoire, si on étend le string on observe une perte de 32 bytes dés que le string dépasse les 16...
 
Dans ce cas il est donc plus judicieux de ne pas allouer de string pour chaque champ séparement mais de leur allouer un espace mémoire commun dans lequel on les sépare à l'aide d'un caractère arbitraire. L'accès au champs individuels se fait alors à l'aide d'une fonction dédiée.
 
 
 

n°660242
Taz
bisounours-codeur
Posté le 01-03-2004 à 18:21:50  profilanswer
 

non, c'est pas un bon raisonnement là, il est même stupide
l'allocateur mémoire alloue plus et il a parfaitement raison de le faire. si tu ne comprends pas, tant pis, mais ne va pas chercher des solutions à la noix pour par perdre un octet. ça serait stupide, long, et contre-performant
 
et puis tu fais tu C, alros utilise malloc et realloc


Message édité par Taz le 01-03-2004 à 18:25:22
n°660504
bjone
Insert booze to continue
Posté le 01-03-2004 à 23:04:17  profilanswer
 

Avander a écrit :

Après investigation un début de réponse, l'usage de new en non malloc ne semble pas être en cause.  
 
Lorsqu'on alloue un string d'un caractère on note que d'office on perd 16 bytes de mémoire, si on étend le string on observe une perte de 32 bytes dés que le string dépasse les 16...
 
Dans ce cas il est donc plus judicieux de ne pas allouer de string pour chaque champ séparement mais de leur allouer un espace mémoire commun dans lequel on les sépare à l'aide d'un caractère arbitraire. L'accès au champs individuels se fait alors à l'aide d'une fonction dédiée.
 
 
 
 


 
et bien tu viens d'apprendre que les allocateurs ont toujours un pas d'allocation (et que de toutes manières les OS fontionnent en pages, de 4Ko ou 4Mo sur les x86), et accessoirement 16 octets ça fait un paragraph(e).

n°660657
avander
Posté le 02-03-2004 à 10:01:54  profilanswer
 

Taz > Je suis d'accord avec toi pour dire que c'est pas idéal, et qu'il faut pas se préoccuper de la cuisine interne de l'allocateur mémoire, la modif que j'avance me permets toutefois de mieux utiliser la mémoire disponible, tous les noms sont chargés et il me reste encore... 25Ko alors qu'avant j'étais à court. Dans la pratique la fin justifie les moyens, hélas.  
 
bjone > Ben oui, je découvre... si tu as d'autres informations concernant ce sujet je suis preneur, est-ce que tu confirme mes conclusions?  
 

n°660762
bjone
Insert booze to continue
Posté le 02-03-2004 à 12:01:14  profilanswer
 

vu que ton programme C est développé en Borland 3.1 sous DOS, tu as plusieurs choix:
 
1) utiliser des farmallocs, et te faire chier avec la segmentation des 64ko.
 
2) tu télécharges OpenWatcom ou DJGPP, et tu portes ton application en mode protégé appellé abusivement mode 32 bits.
 
d'un part tu pourras allouer juqu'à 64 mo de ram (limite des dos-extenders en général)
 
d'autre part, tu utilisesras un cpu actuel avec un meilleur rendement (le mode réel est l'ennemi des CPUs depuis le pentium pro)
 
et encore d'autre part, comme les routines de traitements auront été légèrement retouchés pour travailler avec un modèle mémoire "plat" (flat/linear, enfin non segmenté), ces routines seront presque portable telles quelles sour linux ou sous win32. (et genre insérer tes routines dans une appli graphique faite avec borland c++ builder pour faire un truc vite et propre)

mood
Publicité
Posté le 02-03-2004 à 12:01:14  profilanswer
 

n°661709
avander
Posté le 03-03-2004 à 09:44:48  profilanswer
 

Ah ces jeunes quel enthousiasme!! on jette tout et on recommence :-), ben non je n'ai pas vraiment le choix sauf celui de bidouiller et de coller des rustines...
 
Pour info il s'agit quand même d'une application critique qui tourne sur 20.000 PC animé ( si on peut dire...) de 386, 486 sous MSDOS 6.22 qui ne sont pas équipés de DD, donc tout doit tenir sur une (1!) disquette HD et dans les 640Ko de la mémoire basse... je vous rassure tout de suite c'est pas pour piloter des centrales nucléaires.  
 
 
Donc si tu as des info concernant le fonctionnement de l'allocateur de mémoire dans cet environnement ça m'intéresse toujours...  

n°661827
bjone
Insert booze to continue
Posté le 03-03-2004 à 11:11:20  profilanswer
 

y'a pas 2 ou 4 mo de ram sur tes binious ?
 
j'ai pas dit on jette tout et on recommence, j'ai dit tu changes de compilo, 2/3 trucs à corriger, et t'as du code réutilisable pour plus tard...
 
après ça utilises le système graphique de borland ou c'est du mode texte ?


Message édité par bjone le 03-03-2004 à 11:15:18
n°662482
avander
Posté le 04-03-2004 à 10:13:40  profilanswer
 

salut bjone,  
 
Oui, il y a au moins 2Mo de RAM, mais la mémoire dite haute est déjà utilisé comme ramdisk, il n'est pas envisageable de changer de compilo maintenant... oui, on utilise le système graphique de Borland ( BGI si je ne me trompe)...
 
La modif à l'aire de tenir si on tient encore 6 mois/ 1 an avec c'est bon, après on peut envisager de remplacer le soft et le hard...
 
 
 


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

  [C] Pourquoi cette perte de mémoire?

 

Sujets relatifs
[C] programmation IPC (memoire partagee) sous Unix >> magie inside <<[Oracle 8i] Liaison avec Access : Perte des décimales
[MFC] Fuites mémoire =>help!!une histoire d'allocateur mémoire
[Delphi] Gestion mémoire bizarreGerer (l'ouverture des) les fichiers (en memoire) avec MTS ??
[DB2] Réserver de la mémoire avec des procédures stockées DB2 Cobol[PHP] sessions stockées en mémoire
Detruire un ID en memoire et physiquemnt en DHTML[Algo/PHP] Cassage de tête...gestion des perte d'unité(jeu en ligne)
Plus de sujets relatifs à : [C] Pourquoi cette perte de mémoire?


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