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 de mémoire / valgrind


Sujet :

C

  1. #1
    Membre éprouvé
    Inscrit en
    Janvier 2006
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 161
    Par défaut Allocation de mémoire / valgrind
    bonjour,

    petite question sur la libération de mémoire allouée dynamiquement.

    Le code suivant ne me donne aucune erreur sous valgrind et s'exécute correctement.

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    const int SIZE = 10;
    const int NEW_SIZE = 20;
     
    enum errors {
        OUT_OF_MEMORY = 1
    };
     
    typedef struct {
        int number;
        char* street;
        int zip_code;
        char* city;
        char* country;
    } address_t;
     
    typedef struct {
        char* first_name;
        char* last_name;
        address_t* address;
    } person_t;
     
    int out_of_memory() {
        perror("out of memory\n");
        return OUT_OF_MEMORY;
    }
     
    void print_address(address_t* address) {
        printf("Address:\n");
        printf("Number: %d\n", address->number);
        printf("Street: %s\n", address->street);
        printf("Zip Code: %d\n", address->zip_code);
        printf("City: %s\n", address->city);
        printf("Country: %s\n", address->country);
    }
     
    void print_someone(person_t* person) {
        printf("Person:\n");
        printf("First Name: %s\n", person->first_name);
        printf("Last Name: %s\n", person->last_name);
        print_address(person->address);
    }
     
    int create_someone() {
        address_t* address = calloc(1, sizeof(address_t));
        if (address == NULL) {
            return out_of_memory();
        }
        address->number = 1;
        address->street = "boulevard of broken dreams";
        address->zip_code = 55555;
        address->city = "New York";
        address->country = "USA";
     
        person_t* person = calloc(1, sizeof(person_t));
        if (person == NULL) {
            return out_of_memory();
        }
        person->first_name = "John";
        person->last_name = "Doe";
        person->address = address;
        print_someone(person);
        free(address);
        free(person);
        return 0;
    }
     
    int main(void) {
        int return_code;
        printf("hello, world\n");
        int a[SIZE];
        a[0] = 1;
        int *b, *c;
        b = malloc(SIZE * sizeof(int));
        if (b == NULL) {
            return out_of_memory();
        }
        c = calloc(SIZE, sizeof(int));
        if (c == NULL) {
            return out_of_memory();
        }
        b[0] = 1;
        c[0] = 1;
        int i;
        for (i = 0; i < SIZE; ++i) {
            printf("%d ", c[i]);
        }
        printf("\n");
        c = realloc(c, NEW_SIZE * sizeof(int));
        // TODO ckeck that realloc actually allocated new memory for larger sizes
        for (i = 0; i < NEW_SIZE - SIZE; ++i) {
            c[i+NEW_SIZE-SIZE] = 1;
        }
        for (i = 0; i < NEW_SIZE; ++i) {
            printf("%d ", c[i]);
        }
        printf("\n");
        free(b);
        free(c);
     
        return_code = create_someone();
        if (!return_code) {
            return return_code;
        }
        printf("bye bye, world\n");
        return 0;
    }
    en revanche, dans le main, si j'invoque la fonction create_someone() avant les free(b) et free(c) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        return_code = create_someone();
        if (!return_code) {
            return return_code;
        }
        free(b);
        free(c);
        printf("bye bye, world\n");
    j'ai des fuites mémoires détectées par valgrind :

    $ valgrind --leak-check=yes ./testc
    ==31751== Memcheck, a memory error detector.
    ==31751== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
    ==31751== Using LibVEX rev 1658, a library for dynamic binary translation.
    ==31751== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
    ==31751== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation framework.
    ==31751== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
    ==31751== For more details, rerun with: -v
    ==31751==
    hello, world
    1 0 0 0 0 0 0 0 0 0
    1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
    Person:
    First Name: John
    Last Name: Doe
    Address:
    Number: 1
    Street: boulevard of broken dreams
    Zip Code: 55555
    City: New York
    Country: USA
    ==31751==
    ==31751== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
    ==31751== malloc/free: in use at exit: 120 bytes in 2 blocks.
    ==31751== malloc/free: 5 allocs, 3 frees, 192 bytes allocated.
    ==31751== For counts of detected errors, rerun with: -v
    ==31751== searching for pointers to 2 not-freed blocks.
    ==31751== checked 59,624 bytes.
    ==31751==
    ==31751== 40 bytes in 1 blocks are definitely lost in loss record 1 of 2
    ==31751== at 0x401D38B: malloc (vg_replace_malloc.c:149)
    ==31751== by 0x80486E8: main (main.c:76)
    ==31751==
    ==31751==
    ==31751== 80 bytes in 1 blocks are definitely lost in loss record 2 of 2
    ==31751== at 0x401D487: realloc (vg_replace_malloc.c:306)
    ==31751== by 0x804878F: main (main.c:91)
    ==31751==
    ==31751== LEAK SUMMARY:
    ==31751== definitely lost: 120 bytes in 2 blocks.
    ==31751== possibly lost: 0 bytes in 0 blocks.
    ==31751== still reachable: 0 bytes in 0 blocks.
    ==31751== suppressed: 0 bytes in 0 blocks.
    ==31751== Reachable blocks (those to which a pointer was found) are not shown.
    ==31751== To see them, rerun with: --show-reachable=yes
    Je suppose que c'est normal, mais je ne comprends pas pourquoi la libération de cette mémoire ne peut pas se faire après l'appel à cette méthode. Il y a effectivement d'autres opérations d'allocation de mémoire dans cette méthode, mais j'ai également essayé en ne mettant qu'un printf dans la fonction create_someone(), et le problème est le même.

    J'imagine qu'il y a peut-être des opérations effectuées automatiquement sur le tas lors de l'invocation d'une fonction qui feraient que la libération ne soit plus possible après l'invocation de cette fonction, mais je ne sais pas quoi exactement. Et du coup je ne trouve pas ça super pratique de devoir libérér la mémoire avant d'invoquer n'importe quelle fonction à l'intérieure d'une autre...

    Enfin voilà, c'est probablement un problème de base, mais bon...

  2. #2
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Ta fonction create_someone retourne 0.

    Dans le main tu fait un test sur cette valeur de retour et si elle est à 0 tu termine le programme (tu sort de la fct main), donc tes fonctions free ne seront jamais executée si elle sont positionnées après.

    Pour resumé tu sort de ta fonction main ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    return_code = create_someone();
        if (!return_code) {
            return return_code;
        }

  3. #3
    Membre éprouvé
    Inscrit en
    Janvier 2006
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 161
    Par défaut
    oh mon dieu ! je suis vraiment fatigué, faut que je prenne des vacances...

    merci en tous cas!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [debutant] : Allocation de mémoire dynamique
    Par sam.fet dans le forum Langage
    Réponses: 5
    Dernier message: 15/02/2006, 14h58
  2. Problème d'allocation de mémoire dans la pile
    Par prophet666 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 19/01/2006, 02h22
  3. [Debutant]Allocation de mémoire
    Par gwendal84 dans le forum C
    Réponses: 6
    Dernier message: 07/12/2005, 19h04
  4. Double allocation de mémoire
    Par hunter001 dans le forum C++
    Réponses: 16
    Dernier message: 25/08/2005, 13h53
  5. pb d'allocation de mémoire
    Par shura dans le forum C
    Réponses: 7
    Dernier message: 17/04/2005, 21h10

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