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

Linux Discussion :

Problème de libération de mémoire


Sujet :

Linux

  1. #1
    Candidat au Club
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Points : 3
    Points
    3
    Par défaut Problème de libération de mémoire
    Bonjour,

    J'utilise dans un programme shmget/shmat pour mettre en mémoire partagée des données.

    Dans shmat, je laisse le systeme gerer l'emplacement ou il veut les mettre. (shmaddr à 0)

    Quand le processus se termine, d'après ce que j'ai lu, la mémoire est libérée.
    Seulement quand je lance le 2eme processus qui fait appel à cette mémoire partagée, meme 30 minutes après, il accede toujours à cette mémoire partagée puisque je peux lire les données.
    1- Y a t-il des risques?
    2- Y a t-il moyen de lui demander de detacher cette memoire, sachant que visiblement je ne peux savoir la valeur de shmaddr, et donc pas la vider explicitement avec shmdt?

    Merci

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 296
    Points : 1 803
    Points
    1 803
    Par défaut
    bien evidement qu'il y a des risque ..... ceci est un cas typique de fuite memoire .

    Normal que une shared merory ne soit pas desallouée a la fin du programme . Elle est partagée et le syseme ne sait pas qui (autre process) peut en avoir beson.

    une solution bourrine consiterai a lancer l'application via un shell et lors de la terminaison de celle-ci liberer la memoire via la commande ipcrm.

    Proprement il te faut la marquer comme "a delete" via la commande (fonction) shmat qui elle prend l'ID de ta memoire et nom pas une adrresse.

  3. #3
    Candidat au Club
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Ok je vois ce que tu veux dire..
    je tente ca et je vous tiens au courant

  4. #4
    Candidat au Club
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Est ce qu'il est possible d'obtenir la valeur de char *shmaddr attribué dans char *shmat, car j'aimerais que ce soit le systeme qui determine lui meme l'adressage (je met NULL), et donc pouvoir recuperer la valeur allouée afin de pouvoir la liberer avec shmdt...

    Merci

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par saturne13
    Est ce qu'il est possible d'obtenir la valeur de char *shmaddr attribué dans char *shmat, car j'aimerais que ce soit le systeme qui determine lui meme l'adressage (je met NULL), et donc pouvoir recuperer la valeur allouée afin de pouvoir la liberer avec shmdt...

    Merci
    Ben c'est le retour de la fonction shmat...

    Tu récupéres cette adresse et c'est elle que tu passeras à shmdt.

    Jc

  6. #6
    Candidat au Club
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Je pige pas...

    Voici le bout de code
    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
     
    char *partage_memoire(char *s,int k,int size)
    {
    		int i;
    		key_t key;
    		key=k;
    		int shmid;
    		char *shm;
    		int f;
     
    		if ((shmid = shmget(key, size ,IPC_CREAT)) < 0) {
            perror("shmget error key");
            exit(1);
        }
        if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
            perror("shmat error key");
            exit(1);
        }
     
        for (i = 0; i <= strlen(s); i++)
            *shm++ = s[i];
     
        *shm++='\0';//pour etre sur de l'arret d'assignation
    }
    Si je printf shm après le if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) , il est egal à la chaine de caractères que je veux partager (ca doit etre ce qu'il reste en memoire au lancement precedent).
    Si je printf shm après *shm++ = s[i];, il est egal à rien (pas null, rien)
    Après le *shm++ = s[i];, j'ai tenté un shmdt(shm);, ce qui normalement devrait faire planter le program fils puisque j'ai theoriquement vidé la mémoire, seulement il accède toujours aux ressources.

    Le but final est que la fonction retourne ce qu'il faut pour vider la memoire a la fin du programme, mais pour l'instant j'en suis pas la.. la tentative de vidage se fait pour le moment dans la fonction!

    y a un truc que j'ai pas du saisir...

    [edit]

    J'ai fait des printf de shm partout dans la fonction pour voir, après exctinction de la machine.

    Jamais il ne m'affiche quelque chose.
    Dans ce test, avant la fin de la fonction je fais un shmdt(shm);
    Le program fils arrive quand meme a recuperer la mémoire, et a partir du 2eme lancement du programme, un printf de shm après le ((shm = shmat(shmid, NULL, 0)) == (char *) -1) me donne toujours le résultat qu'il a encore en mémoire.

  7. #7
    Candidat au Club
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Je reprends mon problème à zero, rapport a ce que j'ai compris, ce que pour moi ca devrais faire, et ce que ca ne fait pas...

    J'ai dans le programme principal ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char *key1,key2...........;
    char message[128]="ceci est mon message";
     
    key1=partage_memoire(message,8000,128);
    dans la fonction partage_memoire:
    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
     
    char *partage_memoire(char *s,int k,int size)
    {
    		int i;
    		key_t key;
    		key=k;
    		int shmid;
    		char *shm;
    		int f;
     
    		if ((shmid = shmget(key, size ,IPC_CREAT | 0666)) < 0) {
            perror("shmget error key");
            exit(1);
        }
        if ((shm = shmat(shmid, 0, 0)) == (char *) -1) {
            perror("shmat error key");
            exit(1);
        }
     
        for (i = 0; i <= strlen(s); i++)
            *shm++ = s[i];
     
    			*shm++='\0';
     
    		return shm;
     
    }

    Jusque la tout va bien.

    A la sortie de la fonction partage_memoire, si je fais un:
    printf("0x%x\n",key1);
    j'ai bien l'emplacement memoire.
    ensuite, je fais immédiatement un:
    shmdt(key1);

    ce qui normalement libère la mémoire...

    En dessous de cette ligne, le programme lance le processus fils qui contient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	if ((shmid = shmget(8000, 128, 0666)) < 0) 
    		{
            perror("shmget client");
            exit(1);
        }
    	if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
    		{
            perror("shmat");
            exit(1);
        }
       char *message=shm;
    Normalement, dans le cas présent (enfin pour moi), il ne devrait pas pouvoir lire ce qui est en mémoire...

    Et Ben SI!

    Ou est l'erreur?

  8. #8
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Parce qu'il faut d'abord faire un appel à shmctl :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if(shmctl(shmid, IPC_RMID, NULL)==-1) {
            perror("Shmctl: ");
            return NULL;
        }
    Jc

  9. #9
    Candidat au Club
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    J'ai du mal a tout saisir, d'autant que les nombreux exemples ne parlaient pas de ca...

    Bref, maintenant je retourne l'int donné par shmget, j'utilise shmctl pour liberer la memoire partagée, mais je ne vois pas du coup a quoi sert shmdt etant donné que la mémoire est libérée par shmctl(id, IPC_RMID, NULL); (d'après mes premiers tests).


    En tout cas merci beaucoup

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par saturne13
    J'ai du mal a tout saisir, d'autant que les nombreux exemples ne parlaient pas de ca...

    Bref, maintenant je retourne l'int donné par shmget, j'utilise shmctl pour liberer la memoire partagée, mais je ne vois pas du coup a quoi sert shmdt etant donné que la mémoire est libérée par shmctl(id, IPC_RMID, NULL); (d'après mes premiers tests).


    En tout cas merci beaucoup
    C'est une question de logique je pense :

    shmctl permet de marquer la zone comme étant en voie de destruction. De facon implicite, si c'est le dernier qui a accès à la zone, elle sera détruite sinon le système va attendre le dernier shmdt.

    D'où l'utilité des deux.
    Jc

Discussions similaires

  1. Problème de libération de mémoire avec free()
    Par Nival dans le forum Débuter
    Réponses: 8
    Dernier message: 18/03/2009, 23h06
  2. [Mémoire] Problème de libération de mémoire
    Par CTotophe85 dans le forum C++
    Réponses: 7
    Dernier message: 24/11/2008, 12h47
  3. Problème de libération de mémoire
    Par ridecat dans le forum C
    Réponses: 13
    Dernier message: 06/05/2008, 08h36
  4. problème de libération de mémoire
    Par hamoudasafira dans le forum C++
    Réponses: 3
    Dernier message: 19/03/2007, 18h54
  5. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38

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