IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Allocation mémoire


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 22
    Points : 13
    Points
    13
    Par défaut Allocation mémoire
    Salut à tous.

    Alors j'essaie de comprendre un peu l'allocation mémoire sous windows. J'ai donc fait un tout petit code tout simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include "stdafx.h"
     
    int main(int argc, char* argv[])
    {
    	char *a;
    	while(1)
    	{
    		a = new char[1024];
    		a++;
    	}
    	return 0;
    }
    Comme résultat j'attendais 2 choses :
    la 1è, ça aurait un dépassement de tampon. car en incrémentant a, je pointe sur le segment mémoire situé après a. à la première allocation, ok ça devrait marcher sans problème. mais pour la suite...
    bon j'aurais une interpétation, mais je ne sais pas si elle est juste : en allouant 1024 octet à chaque fois, en admettant que je commence à l'adresse 0, en incrémentant a de 1 octet, je pointe sur de la mémoire déjà allouée par le programme. Donc l'OS accepte (je tourne sous Win XP sp2 pour précision).

    la 2è, c'est que le programme aurait pris de + en + de mémoire jusqu'à ce qu'il n'y en ait plus de disponible. Or c'est monté jusqu'à 110 Mo puis redescendu vers 10Mo à peu près constant. Est-ce que l'OS libère de la mémoire au fur et à mesure ? d'un côté c'est bien car ça ne plante pas, mais si jamais on avait réellement besoin de cette mémoire, ben pas terrible.

    Enfin voilà, merci de m'éclairer sur ces points. Désolé si ces questions ont l'air un peu bête...

    ++

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 38
    Points : 40
    Points
    40
    Par défaut
    Bonjour,

    Au démarrage de ton programme, a pointe vers une zone mémoire non défini.
    1e tour de boucle
    Allocation de 1024 bytes --> a pointe vers une bonne zone mémoire à l'adresse 10000 par exemple
    a++, le pointeur a pointe maitenant vers la zone mémoire 10001 (qui est valide)

    2e tour de boucle
    Allocation de 1024 bytes --> a pointe vers une bonne zone mémoire à l'adresse 15000 par exemple
    la zone mémoire allouée à l'adresse 10000 est perdue
    a++, le pointeur a pointe maitenant vers la zone mémoire 15001 (qui est valide)

    et ainsi de suite.


    Maintenant pourquoi tu montes jusqu'à 110 Mb puis le programme se stabilise à 10 Mb, je ne sais pas si l'OS y est pour quelquechose.

    Je me demande si ce n'est pas le compilateur Visual C++ qui en mode Debug gère l'utilisation de la mémoire.

    - As-tu le même comportement si tu lances ton programme en mode Release ?
    - As-tu le même comportement si tu lances ton programme en dehors du compilateur (donc en cliquant directement sur le nom de l'exécutable produit) ?

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 22
    Points : 13
    Points
    13
    Par défaut
    Merci d'avoir répondu.

    Bon je l'ai compilé en Release et ça donne la même chose. et je lance toujours le programme à partir de l'invite de commandes.

    a++, le pointeur a pointe maitenant vers la zone mémoire 15001 (qui est valide)
    c'est donc bien ça. l'adresse est valide car il y a 1024 octets alloués. au moins la première question résolue !

    la zone mémoire allouée à l'adresse 10000 est perdue
    je suis d'accord, plus aucun pointeur ne pointe sur cette zone mémoire, mais est-ce pour autant que l'OS libère tout seul la mémoire ?
    Ce serait une explication plus que plausible, mais l'exécutable quand il tourne prend tout de même 10 Mo après s'être stabilisé... il ne le ferait donc qu'après un certain temps...

    En tout cas lors des premières secondes, il est monté à 200 Mo en mode release !

    Merci encore !

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Deux remarques :
    - Premier point, j'ai l'impression qu'il y a possibilité de mésentente sur un point. a++ n'incrémente pas l'adresse de a d'un octet, mais de la taille d'un élément pointé. Ici, c'est identique, puisque a et un pointeur sur char, mais ce n'est pas le cas général.

    - Pour ton second point, il n'y a pas de raison que l'os libère la mémoire alors que ton programme pourrait vouloir l'utiliser. J'ai testé sur ma machine (win XP, msdev 8 beta 2, 1go ram) ton programme, et j'ai eu le comportement suivant :
    - Jusqu'à utiliser toute la RAM (1Go) : Croissance très rapide de la mémoire utilisée (quasi immédiat)
    - De 1Go à 2Go, taille mémoire max configurée, croissance beaucoup plus lente due au faite que l'OS est obligé d'utiliser du swap disque.
    En bref, un comportement différent de celui que tu décris, et plus logique. Quel est ton environement ?

    Autrement, si new échoue, il est sencé lancer une exception, mais sur des vieux compilateurs (genre MSVC 6, j'ai vu une microsofterie à la stdafx dans ton programme), il retourne NULL en cas d'échec. Peut-être en apprendras tu plus en testant la valeur de retour.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2003
    Messages : 65
    Points : 73
    Points
    73
    Par défaut
    Pour ta première question, tu pourrais donner n'importe quelle valeur à la variable a sans causer de problème. Par exemple a+=1024. Le problème se présentera seulement lorsque tu voudras lire le contenu de cette adresse. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char *a;
    char c;
     
    a = 0;    // Ok
    c = *a;  // Problème !

  6. #6
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 22
    Points : 13
    Points
    13
    Par défaut
    Salut =)

    a++ n'incrémente pas l'adresse de a d'un octet, mais de la taille d'un élément pointé
    euh... je n'ai pas tout compris là. Bon réussi à comprendre que l'adresse pointée par a n'augmente pas d'un octet, car j'incrémente la valeur de a, et non de la zone mémoire. Mais quelle est la structure d'un pointeur ? car un pointeur tient sur 4 octets, même pour un char *, donc c'est un peu particulier. Il doit y avoir l'adresse de début et la taille, non ?
    il n'y a pas de raison que l'os libère la mémoire alors que ton programme pourrait vouloir l'utiliser
    bon ça me rassure, en effet c'est ce que je pensais. Mais j'ai essayé ce matin sur mon PC du taf, et c'est monté jusqu'à 400 Mo, ensuite la mémoire paginée augmente, et ça se stabilise aux alentours de 800Mo.
    En bref, un comportement différent de celui que tu décris, et plus logique
    ben oui, chez toi c'est le résultat que j'attendais, mais je n'obtiens pas !

    Je travaille sur XP sp2.

    Je vais essayé comme tu l'as conseillé de tester le retour de new, peut-être que la réponse est là !

    Merci beaucoup :-D

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    euh... je n'ai pas tout compris là. Bon réussi à comprendre que l'adresse pointée par a n'augmente pas d'un octet, car j'incrémente la valeur de a, et non de la zone mémoire. Mais quelle est la structure d'un pointeur ? car un pointeur tient sur 4 octets, même pour un char *, donc c'est un peu particulier. Il doit y avoir l'adresse de début et la taille, non ?
    Un pointeur est simplement une adresse mémoire, pas une structure composée de plusieurs choses comme tu sembles le penser. C'est juste un entier, quoi.

    Pour résumer ce que tu n'as pas compris, incrémenter un pointeur n'ajoutera pas 1 à sa valeur, mais sizeof(type). Si c'est un pointeur sur int, cela ajoutera donc sizeof(int) à l'adresse.

  8. #8
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 22
    Points : 13
    Points
    13
    Par défaut
    Bon désolé du retard, et en plus je n'ai pas eu le temps de tester le retour de new. Mais j'aimerais juste avoir une précision sur les pointeurs : est-ce que les 4 octets correspondent à :

    2 octets pour le segment mémoire
    2 octets pour l'offset

    C'est bien ça ou pas ? J'ai lu sur un cours d'assembleur prix sur ce site que la mémoire était adressée comme ça. cela est également vrai pour le C et C++ ?

    voilà, merci pour vos réponses.

  9. #9
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    C'est bien ça ou pas ? J'ai lu sur un cours d'assembleur prix sur ce site que la mémoire était adressée comme ça. cela est également vrai pour le C et C++ ?
    Dés le démarrage de Windows, le CPU est commuté en mode protégé. Windows utilise alors un type de de mémoire que l'on appelle "flat", soit "modèle de mémoire plat".

    La totalité des adresses accessible sur 32 bits l'est uniquement par une adresse d'offset mais plus de segment (donc de 0 à 0x0FFFFFFFF).

    Là c'est du point de vue des programmes, par contre Windows gère quand même des segments au niveau du Kernel, mais c'est complètement obscurcit au niveau des programmes, eux ne voit qu'un seul et même espace d'adressage.

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    J'ajouterai que c'est le genre de considération dont on ne devrait vraiment pas se soucier en C++.

Discussions similaires

  1. Allocation mémoire
    Par Viper1007 dans le forum C
    Réponses: 10
    Dernier message: 22/12/2005, 17h33
  2. Pb d'allocation mémoire malloc
    Par oz80 dans le forum C++
    Réponses: 5
    Dernier message: 18/11/2005, 18h23
  3. Limite Allocation Mémoire d'un tableau d'entier
    Par l9ft b9hind dans le forum C++
    Réponses: 5
    Dernier message: 27/10/2005, 20h29
  4. [Pointeur] Allocation mémoire
    Par Rayek dans le forum Langage
    Réponses: 22
    Dernier message: 20/05/2005, 11h26
  5. Allocation mémoire dynamique
    Par ITISAR dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 21/01/2005, 10h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo