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 :

Question allocation mémoire MAX avec malloc


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    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
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 : 1 565
    Points : 7 648
    Points
    7 648
    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 confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    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 confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    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
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Pour avoir 2.5G accessible, il te faut donc compiler en mode 64bits

  6. #6
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    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 confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    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
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    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