1. #1
    Membre averti
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 690
    Points : 446
    Points
    446

    Par défaut Question allocation mémoire MAX avec malloc

    Hello,

    J'aurais besoin de mettre en mémoire un fichier de log pour le parser.
    En l’occurrence, il pèse 226MB et quand je tente de mettre le contenu de mon fichier dans un string, l'allocation échoue.

    Pour comprendre un peu plus et trouver la valeur max, j'ai crée une boucle qui me fait des malloc successifs en incrémentant de 1 MB par 1MB, de 0 jusqu'à 100MB pour voir jusqu'où je peux aller et il semblerait que le max que je puisse allouer est 62MB.

    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
     
            char *p = NULL;
            int i = 0;
            int total_i = 0;
            for ( i = 0 ; i<100 ; i++ )
            {
                if ( allocate_1D_c( i*1024*1024 ) )
                {
                    total_i+=i;
                    printf("\n%d MB\nTotal MB %d", i, total_i);
                    free(p),p=NULL;
                }
                else
                {
                    printf("\nFAILED %d MB",i);
                }
            }
            system("pause");
    Dans mon fichier de log, le résultat est le suivant :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    allocate.h::allocate_1D_c -> Not enough space, 63.000000
    allocate.h::allocate_1D_c -> Not enough space, 64.000000
    allocate.h::allocate_1D_c -> Not enough space, 65.000000
    allocate.h::allocate_1D_c -> Not enough space, 66.000000
    allocate.h::allocate_1D_c -> Not enough space, 67.000000
    allocate.h::allocate_1D_c -> Not enough space, 68.000000
    allocate.h::allocate_1D_c -> Not enough space, 69.000000
    allocate.h::allocate_1D_c -> Not enough space, 70.000000
    allocate.h::allocate_1D_c -> Not enough space, 71.000000
    allocate.h::allocate_1D_c -> Not enough space, 72.000000
    allocate.h::allocate_1D_c -> Not enough space, 73.000000
    allocate.h::allocate_1D_c -> Not enough space, 74.000000
    allocate.h::allocate_1D_c -> Not enough space, 75.000000
    allocate.h::allocate_1D_c -> Not enough space, 76.000000
    allocate.h::allocate_1D_c -> Not enough space, 77.000000
    allocate.h::allocate_1D_c -> Not enough space, 78.000000
    allocate.h::allocate_1D_c -> Not enough space, 79.000000
    allocate.h::allocate_1D_c -> Not enough space, 80.000000
    allocate.h::allocate_1D_c -> Not enough space, 81.000000
    allocate.h::allocate_1D_c -> Not enough space, 82.000000
    allocate.h::allocate_1D_c -> Not enough space, 83.000000
    allocate.h::allocate_1D_c -> Not enough space, 84.000000
    allocate.h::allocate_1D_c -> Not enough space, 85.000000
    allocate.h::allocate_1D_c -> Not enough space, 86.000000
    allocate.h::allocate_1D_c -> Not enough space, 87.000000
    allocate.h::allocate_1D_c -> Not enough space, 88.000000
    allocate.h::allocate_1D_c -> Not enough space, 89.000000
    allocate.h::allocate_1D_c -> Not enough space, 90.000000
    allocate.h::allocate_1D_c -> Not enough space, 91.000000
    allocate.h::allocate_1D_c -> Not enough space, 92.000000
    allocate.h::allocate_1D_c -> Not enough space, 93.000000
    allocate.h::allocate_1D_c -> Not enough space, 94.000000
    allocate.h::allocate_1D_c -> Not enough space, 95.000000
    allocate.h::allocate_1D_c -> Not enough space, 96.000000
    allocate.h::allocate_1D_c -> Not enough space, 97.000000
    allocate.h::allocate_1D_c -> Not enough space, 98.000000
    allocate.h::allocate_1D_c -> Not enough space, 99.000000
    Sachant que je dispose de 16Go de RAM dont 6Go en cours d'utilisation à l'instant soit à priori 10Go de libre. (Win10)
    En regardant le gestionnaire des tâches, je constate que la mémoire allouée se cumule au file de la boucle. C'est pour ça que j'ai ajouté dans la boucle une variable pour compter le cumul de la mémoire allouée ( réussi 62 ), ce qui donne 1953MB. Et le processus correspondant à l’exécution du programme fait 1958MB à la fin. Cela correspond moins la mémoire système pour l'invite de commande qui doit prendre 5MB je suppose.
    Je ne comprends pas pourquoi la mémoire n'est pas libérée en instantanée comme demandée dans la boucle mais seulement à la fin.

    La question finale est comment puis-je contourner le fait que je ne puisse allouer que 62MB max via un malloc ? ( si c'est faisable ) .

    Merci d'avance pour vos luminaires.

    Cordialement.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 763
    Points : 3 810
    Points
    3 810

    Par défaut

    Bonjour,

    malloc() peut allouer l'ensemble de la mémoire physique accessible à une application (limité à 2G ou 3G sur une application 32bits.)
    Ton code ne libère jamais la mémoire, il y a bien 2G d'alloué en tout.

  3. #3
    Membre averti
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 690
    Points : 446
    Points
    446

    Par défaut

    LOL... corrigé pour la libération. Fallait aller dormir.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (p=allocate_1D_c( i*1024*1024 ))
    J'arrive cependant toujours pas à allouer les 250Mb dans le code pour parser -.-
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  4. #4
    Membre averti
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 690
    Points : 446
    Points
    446

    Par défaut

    A priori, c'est ma structure 2D soit un tableau à 2 dimensions de i lignes et de 1024 colonnes qui nécessite 2.5GB de mémoire pour être allouée.
    L’échec se situe là compte tenu de ta remarque précédente.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 763
    Points : 3 810
    Points
    3 810

    Par défaut

    Pour avoir 2.5G accessible, il te faut donc compiler en mode 64bits

  6. #6
    Membre averti
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 690
    Points : 446
    Points
    446

    Par défaut

    Je n'ai pas besoin d'autant même s'il serait intéressant que je me penche sur la question.
    Je n'ai pas anticipé la taille de la structure, le fichier de log fait 3 millions de lignes et je reservais 1ko pour les colonnes.
    Je fais une passe avant pour déterminer le nombre de colonnes max et en réalité je n'ai besoin que de 300 octets.
    Je divise pas 3 la taille nécessaire. L'idéal étant que je crée une structure qui alloue par ligne la taille nécessaire par chacune d'elle.
    Il faudrait que je reprenne pas mal de choses pour cela. A voir pour la prochaine fois.
    Merci pour vos réponses jusqu'à la prochaine galère ^^
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  7. #7
    Membre averti
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 690
    Points : 446
    Points
    446

    Par défaut

    Je pensais avoir fais le nécessaire pour qu'en cas d'échec d'allocation mémoire, je retrouve une erreur dans mon fichier de log.
    Visiblement ce n'est pas le cas.
    Pour la fonction create_2D_c en l'occurrence. Une idée de ce que je ne fais pas correctement ?
    Ci dessous et entre autres les fonctions utiles :
    create_2D_c utilise notamment allocate_2D_c pour le principal.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    void destroy_1D_c( t_1Dc *s)
    {
        if (s)
        {
            if (s->da != NULL )
                deallocate_1D_c(s->da);
     
            free(s);
        }
        s=NULL;
    }
     
    t_1Dc *create_empty_1D_c()
    {
        t_1Dc *s = NULL;
        if ( !(s = (t_1Dc*)malloc(sizeof(t_1Dc))) )
            fprintf(logger, "create_da.h::create_empty_1D_c -> %s\n", strerror(errno));
     
        return s;
    }
     
    t_1Dc *create_1D_c( unsigned long long int x )
    {
        t_1Dc *s = NULL;
        if ( (s = create_empty_1D_c()) )
        {
            if ((s->da = allocate_1D_c(x)))
                s->x = x;
     
            else fprintf(logger, "create_da.h::create_1D_c -> %s\n", strerror(errno));
        }
        else fprintf(logger, "create_da.h::create_1D_c -> %s\n", strerror(errno));
        return s;
    }
     
    void displayda_1D_c( t_1Dc *s, const char *name)
    {
       if (s)
       {
           printf("-----------------%s-----------------\n", name);
           unsigned long long int i;
           for (i=0 ; i<s->x ; i++)
               printf("da[%I64u]=%c\n", i, s->da[i]);
       }
       else fprintf(logger, "display_da.h::displayda_1D_c -> %s\n", strerror(errno));
    }
     
    void deallocate_2D_c( char **p, unsigned long long int x )
    {
        if (p)
        {
            unsigned long long int i;
            for ( i=0 ; i<x ; i++ )
                free(p[i]), p[i]=NULL;
     
            free(p), p=NULL;
        }
        else fprintf(logger,"deallocate.h::deallocate_2D_c -> %s\n",strerror(errno));
    }
     
    char **allocate_2D_c( unsigned long long int x, unsigned long long int y )
    {
        char **t = NULL;
        if ( (t = (char**)malloc( x*sizeof(char*))) )
        {
            unsigned long long int i;
            for ( i=0 ; i<x ; i++ )
            {
                if ( !( t[i] = allocate_1D_c(y) ) )
                {
                    fprintf(logger,"allocate.h::allocate_2D_c -> %s\n", strerror(errno));
                    deallocate_2D_c(t,i-1);
                    i=x;
                }
            }
        }
        else fprintf(logger,"allocate.h::allocate_2D_c -> %s\n", strerror(errno));
        return t;
    }
     
    void display_2D_c( char **p, unsigned long long int x, unsigned long long int y, const char *name)
    {
       if(p)
       {
           printf("-----------------%s-----------------\n", name);
           unsigned long long int i,j;
           for (i=0 ; i<x ; i++)
               for (j=0 ; j<y ; j++)
                   printf("p[%I64u][%I64u]=%c\n", i, j, p[i][j]);
       }
       else fprintf(logger,"display.h_da::display_2D_c -> %s\n",strerror(errno));
    }
     
    void destroy_2D_c( t_2Dc *s)
    {
        deallocate_2D_c(s->da, s->x); free(s); s=NULL;
    }
     
    t_2Dc *create_empty_2D_c()
    {
        t_2Dc *s = NULL;
        if ( !(s = (t_2Dc*)malloc(sizeof(t_2Dc))) )
            fprintf(logger, "create_da.h::create_empty_2D_c -> %s\n", strerror(errno));
     
        return s;
    }
     
    t_2Dc *create_2D_c( unsigned long long int x, unsigned long long int y )
    {
        t_2Dc *s = NULL;
        if ( (s = create_empty_2D_c()) )
        {
            if ((s->da = allocate_2D_c(x,y)))
                s->x = x, s->y = y;
     
            else fprintf(logger, "create_da.h::create_2D_c -> %s\n", strerror(errno));
        }
        else fprintf(logger, "create_da.h::create_2D_c -> %s\n", strerror(errno));
        return s;
    }
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  8. #8
    Membre expérimenté Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    mai 2010
    Messages
    397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : mai 2010
    Messages : 397
    Points : 1 361
    Points
    1 361

    Par défaut

    Bonjour,
    Citation Envoyé par dalfab Voir le message
    Pour avoir 2.5G accessible, il te faut donc compiler en mode 64bits
    Avoir un exécutable pour une architecture 64 bits ne résout absolument pas le problème sachant que le problème en question peut tout à fait être résolue par une simple projection en mémoire du fichier. Ici, il faut juste revoir la façon de traiter/extraire les données de votre fichier. Et on ne résout pas un problème en le déplaisants. Si votre programme est gourmand en ressource sous une architecture 32 bits, il le sera tout aussi bien sous une architecture 64 bit. En clair si lors de ça conception le programme est gourmand en ressource, il le sera tout aussi bien sous architecture 64 bits.


    Citation Envoyé par darkwall_37 Voir le message
    Je pensais avoir fais le nécessaire pour qu'en cas d'échec d'allocation mémoire, je retrouve une erreur dans mon fichier de log.
    Visiblement ce n'est pas le cas.
    Pour la fonction create_2D_c en l'occurrence. Une idée de ce que je ne fais pas correctement ?
    Ci dessous et entre autres les fonctions utiles :
    create_2D_c utilise notamment allocate_2D_c pour le principal.
    Si dans votre fichier log vous n’avez pas d’information vous disant qu’il y a échec d’allocation, c’est soit les allocations ont fonctionnée ou vous n'écriez pas dans le fichier les informations d’échec mémoire voire ne les traiter pas. Mais dans tous les cas malloc échoue rarement. S’il échoue et que vous gérer très mal l'échec de vos ressources malgré vos précautions vous obtiendrez systématiquement une erreur de segmentation.
    Je n'est pas fait l'analyse de votre code, car il manque certains éléments, mais sinon vous avez des outils pour traquer des fuite mémoire comme Valgrin par exemple.
    À bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

Discussions similaires

  1. Question Allocation Mémoire Conditionnelle
    Par JasBeckC dans le forum Débuter
    Réponses: 12
    Dernier message: 27/10/2014, 20h56
  2. Allocation mémoire : tableau vs malloc
    Par scorbo dans le forum Débuter
    Réponses: 4
    Dernier message: 15/06/2007, 12h47
  3. Réponses: 4
    Dernier message: 20/11/2006, 01h02
  4. Pb d'allocation dynamique avec malloc
    Par Magicmax dans le forum C
    Réponses: 5
    Dernier message: 12/12/2005, 01h04
  5. Pb d'allocation mémoire malloc
    Par oz80 dans le forum C++
    Réponses: 5
    Dernier message: 18/11/2005, 17h23

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