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 :

C++ diff�rence entre d�claration static et dynamic


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Ao�t 2008
    Messages
    27
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2008
    Messages : 27
    Par d�faut C++ diff�rence entre d�claration static et dynamic
    Bonjour,

    Je ne comprends pas pourquoi mon programme n'utilise pas la m�me quantit� de m�moire selon que j'alloue de la m�moire dynamiquement ou statiquement.

    Voici mon exemple :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #include <iostream>
    #include <vector>
     
    void with_pointer(int size){
    	std::vector<int*> v(size);
    	for(int i = 0; i < size; ++i){
    		//v[i] = (int*)malloc(sizeof(int));
    		v[i] = new int();
    	}
    	system("PAUSE");
    }
    void without_pointer(int size){
    	std::vector<int> v(size);
    	system("PAUSE");
    }
     
    int main(int argc, char* argv[]){
    	int size = 1000000;
     
    	//with_pointer(size);//67 400KB
     
    	without_pointer(size);//4 800KB
    	return 0;
    }
    Mon but �tant de voir l'espace m�moire utilis� (avec le gestionnaire des t�ches) sur une allocation de 1 000 000 de int (soit 4Mo). En static, donc la version without_pointer utilise bien une quantit� de m�moire de l'ordre de 4Mo. En dynamique, c'est beaucoup plus! Je comprendrais que la m�moire double car j'utilise un tableau de pointer qui pointent vers des int. Mais l�, le rapport est tr�s diff�rent.

    D'o� cela vient-il ?

    Merci

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    734
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 734
    Par d�faut
    Ta comparaison n'a pas beaucoup de sens:
    • � ma connaissance, un vector alloue sur la heap quoi qu'il arrive
    • tu ne peux comparer des valeurs int a des pointeurs sur int, en fonction des architecture un pointeur peut �tre plus petit (EDIT: peu probable), ou plus grand (EDIT: cf adressage 64 bits...) qu'un int en m�moire
    • tu ne peux pas comparer non plus un vector seulement r�serv� (ton cas dit "sur la pile") avec un vector r�serv� ET rempli (ton cas dit "sur le heap")

  3. #3
    Membre chevronn�
    Inscrit en
    D�cembre 2010
    Messages
    290
    D�tails du profil
    Informations forums :
    Inscription : D�cembre 2010
    Messages : 290
    Par d�faut
    Il faut savoir que malloc() ne dit pas qu'il alloue exactement la taille demand�e. Beaucoup d'impl�mentations allouent un peu plus, ne serait-ce que pour du "book-keeping" ou pr�voir une r�allocation ult�rieure.
    Faire 1 millions d'allocations de 4 octets est assez suspect, �a ne correspond pas � ce que font la plupart des programmes, donc �a se comprend que la biblioth�que standard ne soit pas optimis�e pour ce cas-l�.

    J'ai une question toutefois : quel outil as tu utilis� pour obtenir les chiffres que tu donnes ?

  4. #4
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 299
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 299
    Billets dans le blog
    2
    Par d�faut
    Citation Envoy� par therwald Voir le message
    � ma connaissance, un vector alloue sur la heap
    Sauf si tu sp�cifie ton propre allocator (2eme type template de la classe vector).

    En fait, un int[N] et un vector<int>(N) ont la m�me taille en m�moire (� quelques bits pr�s), que soit sur la pile ou sur le tas. De m�me, un (int*)[N] vector<int*>(N) occuperont le m�me espace m�moire.

    En revanche, et pour paraphraser therwald, stocker un int et un int* ce n'est pas la m�me chose. Un int* est un pointeur sur un int, il faut donc ajouter la m�moire utilis�e pour le pointeur en lui-m�me.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Ao�t 2008
    Messages
    27
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2008
    Messages : 27
    Par d�faut
    Merci de pour vos r�ponses

    Citation Envoy� par therwald Voir le message
    tu ne peux comparer des valeurs int a des pointeurs sur int, en fonction des architecture un pointeur peut �tre plus petit (EDIT: peu probable), ou plus grand (EDIT: cf adressage 64 bits...) qu'un int en m�moire
    Je compare pour une architecture donn�e donc si .. il suffit de connaitre la taille d'un pointeur et d'un int. Pour moi, une allocation via un pointeur va allouer un espace pour ce pointeur + un espace pour la valeur stock�e.

    Citation Envoy� par therwald Voir le message
    tu ne peux pas comparer non plus un vector seulement r�serv� (ton cas dit "sur la pile") avec un vector r�serv� ET rempli (ton cas dit "sur le heap")
    pourquoi ?


    Citation Envoy� par phi1981 Voir le message
    Il faut savoir que malloc() ne dit pas qu'il alloue exactement la taille demand�e. Beaucoup d'impl�mentations allouent un peu plus, ne serait-ce que pour du "book-keeping" ou pr�voir une r�allocation ult�rieure.
    Faire 1 millions d'allocations de 4 octets est assez suspect, �a ne correspond pas � ce que font la plupart des programmes, donc �a se comprend que la biblioth�que standard ne soit pas optimis�e pour ce cas-l�.

    J'ai une question toutefois : quel outil as tu utilis� pour obtenir les chiffres que tu donnes ?
    J'ai obtenu ces chiffres avec le gestionnaire des t�ches de windows. Je comprends que le vector peut �tre plus gros pour du book keeping mais de l� � avoir une taille 7 fois sup�rieur..

    Citation Envoy� par r0d Voir le message
    En revanche, et pour paraphraser therwald, stocker un int et un int* ce n'est pas la m�me chose. Un int* est un pointeur sur un int, il faut donc ajouter la m�moire utilis�e pour le pointeur en lui-m�me.
    Comme dit dans mon premier message, �a ne m'�tonnerait pas de retrouver la taille occup� en m�moire des pointeurs, cela doublerait l'espace occup� en m�moire (mes pointeurs font 4octets, un int faisant 4octets sous mon OS).
    Ce que je me demande, c'est que ce passe-t-il pour allouer 7 fois plus de m�moire qu'il n'en a besoin ?

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    734
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 734
    Par d�faut
    Citation Envoy� par lovoo Voir le message
    Je compare pour une architecture donn�e donc si .. il suffit de connaitre la taille d'un pointeur et d'un int. Pour moi, une allocation via un pointeur va allouer un espace pour ce pointeur + un espace pour la valeur stock�e.
    +/- les diff�rences dues aux strat�gies d'alignement (entre autres). Je n'ai pas dit que c'est variable � architecture donn�e, juste que ce n'est pas n�cessairement aussi simple que tu le supposes.

    Citation Envoy� par lovoo Voir le message
    Citation Envoy� par therwald
    tu ne peux pas comparer non plus un vector seulement r�serv� (ton cas dit "sur la pile") avec un vector r�serv� ET rempli (ton cas dit "sur le heap")
    pourquoi ?
    Parce que le vector n'alloue pas forc�ment ajout par ajout pour des raisons d'optimisation, mais plut�t par blocs, donc le fait d'ajouter n �l�ments, surtout s'ils sont nombreux, change la taille du vector.

    Citation Envoy� par lovoo Voir le message
    J'ai obtenu ces chiffres avec le gestionnaire des t�ches de windows. Je comprends que le vector peut �tre plus gros pour du book keeping mais de l� � avoir une taille 7 fois sup�rieur..
    Et l� tu as encore entre toi et ce qui se passe la strat�gie du syst�me dont on ne sait pas grand chose � part qu'il se donne le droit de pr�r�server pour �viter de passer sa vie � chercher des blocs de m�moire disponibles (et pour limiter la fragmentation), + les temps de mise � jour de l'affichage de gestionnaire de t�che qui font que tu n'as qu'un ordre de grandeur liss� dans le temps de la conso m�moire...

  7. #7
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par lovoo Voir le message
    Comme dit dans mon premier message, �a ne m'�tonnerait pas de retrouver la taille occup� en m�moire des pointeurs, cela doublerait l'espace occup� en m�moire (mes pointeurs font 4octets, un int faisant 4octets sous mon OS).
    Ce que je me demande, c'est que ce passe-t-il pour allouer 7 fois plus de m�moire qu'il n'en a besoin ?
    Il y a aussi un surco�t quand compil� en debug (avec VS2012, ~2 fois plus de m�moire utilis�es)

    Sinon (release, 64 bits)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void with_pointer(int size){
    	std::vector<int*> v(size);
    	system("PAUSE");
    } // -> 8200 Ko
     
    void without_pointer(int size){
    	std::vector<int> v(size);
    	system("PAUSE");
    } // -> 4288 Ko
    Il est peut �tre impossible de r�server seulement 4 octets sur le tas, d'o� le surco�t.

    edit: �a semble �tre le cas
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <iostream>
    #include <vector>
     
    template <class T>
    void alloc(int size) {
    	std::vector<T*> v(size);
    	for(int i = 0; i < size; ++i){
    		v[i] = new T();
    	}
    	system("PAUSE");
    }
     
    int main(int argc, char* argv[]){
    	const int size = 1000000;
     
    	//alloc<char>(size); // 70 820 Ko
    	alloc<double>(size); // 70 824 Ko
     
    	return 0;
    }

  8. #8
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Entre les histoires d'alignement et celles de bookkeeping, new int() bouffera bien plus de quatre octets. Et encore plus en Debug, avec les gardes au d�but et � la fin de chaque zone allou�e...

    Voici un code test� sous Visual Studio 2010:
    Code C++ : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <iostream>
     
    inline void      * to_void(void      * p) { return p; }
    inline void const* to_void(void const* p) { return p; }
     
    int main(void)
    {
    	int *p1 = new int;
    	int *p2 = new int;
    	ptrdiff_t diff = reinterpret_cast<char*>(p2) - reinterpret_cast<char*>(p1);
    	std::cout << "p1: " << to_void(p1) << " - p2: " << to_void(p2) << " - diff: " << diff << " bytes" << std::endl;
    	delete p1, p1=NULL;
    	delete p2, p2=NULL;
    	return 0;
    }
    Code X, sortie Debug : S�lectionner tout - Visualiser dans une fen�tre � part
    p1: 001B1F30 - p2: 001B1F60 - diff: 48 bytes
    Code X, sortie Release : S�lectionner tout - Visualiser dans une fen�tre � part
    p1: 00311EB0 - p2: 00311EC0 - diff: 16 bytes
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,
    Citation Envoy� par Iradrille Voir le message
    Il y a aussi un surco�t quand compil� en debug (avec VS2012, ~2 fois plus de m�moire utilis�es)

    Sinon (release, 64 bits)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void with_pointer(int size){
    	std::vector<int*> v(size);
    	system("PAUSE");
    } // -> 8200 Ko
     
    void without_pointer(int size){
    	std::vector<int> v(size);
    	system("PAUSE");
    } // -> 4288 Ko
    Il est peut �tre impossible de r�server seulement 4 octets sur le tas, d'o� le surco�t.
    C'est, surtout, parce qu'un int est, classiquement (bien que l'on pourrait trouver une architecture sur laquelle ce ne soit pas le cas ) cod� sur 32 bits (4 bytes), alors qu'un pointeur ne l'est pas forc�ment vu qu'il doit �tre cod� sur une taille qui permette de repr�senter "au minimum l'ensemble des adresses m�moire accessible".

    sur une architecture 64 bits, la taille d'un pointeur est souvent (bien qu'il me semble qu'elle soit un peu inf�rieur sous MacOs ) de... 64 bits, soit 8 bytes.

    Apr�s, la somme de l'espace m�moire r�serv� pour les diff�rents �l�ments + (dans le cas d'un pointeur) l'espace m�moire utilis� par les �l�ments point�s + l'espace m�moire utilis� par la structure interne du tableau ainsi que l'endroit o� sont plac�s les �l�ments (pile vs tas) est strictement d�pendant de l'impl�mentation.

    On pourrait ainsi parfaitement envisager une impl�mentation qui calculerait la taille de l'espace m�moire n�cessaire pour repr�senter les diff�rents �l�ments (+, pourquoi pas la taille du tableau) et qui d�ciderait d'utiliser la pile ou le tas en fonction de cette valeur.

    En effet, une structure proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    template <typename Type, int nb>
    struct StackHolded{
        enum{ size= nb};
        T data[size];
    };
    pourrait parfaitement �tre utilis�e tant que l'espace m�moire total utilis� est inf�rieur �, mettons, 140 (bytes).

    Le compilateur ne se plaindra jamais de ne pas pouvoir utiliser size car les �num�rations sont des constantes de compilation.

    Et l'on pourrait parfaitement utiliser sizeof(Type)* nb pour �valuer l'espace m�moire n�cessaire (et donc savoir s'il est inf�rieur ou non � 140 selon l'exemple) parce que le r�sultat de sizeof est lui aussi une constante de compilation

    Et l'on pourrait m�me parfaitement envisager de faire en sorte que size soit directement inclus dans l'array (au d�but ou � la fin, selon notre bon vouloir) d�s le moment o� la taille d'un size_t est un multiple de la taille de Type (autrement dit, pour char, short int et size_t et similaire)

    Mais ca, c'est du seul ressort du d�veloppeur de la classe vector
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

Discussions similaires

  1. JQuery diff�rence entre d�claration
    Par Pidev1302 dans le forum jQuery
    R�ponses: 3
    Dernier message: 05/10/2014, 19h11
  2. Diff�rences entre d�clarations avec Set et LinkedHashSet
    Par Sinakhine dans le forum D�buter avec Java
    R�ponses: 1
    Dernier message: 22/10/2012, 00h16
  3. Diff�rence entre public static
    Par moooona dans le forum D�buter avec Java
    R�ponses: 1
    Dernier message: 24/05/2008, 15h23
  4. R�ponses: 2
    Dernier message: 16/12/2007, 01h35
  5. Quelle est la diff�rence entre ces deux d�clarations ?
    Par sidahmed dans le forum D�buter
    R�ponses: 15
    Dernier message: 04/10/2007, 19h59

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