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 :

pointeur et memoire partagée


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 14
    Par défaut pointeur et memoire partagée
    Bjr, j'ai une methode en C qui attribue une adresse memoire à une structure de donnees qu'elle a reçu en parametre. et a la sortie de cette methode, je dois nourrir les champs de cette stucture. Je recois une erreur:

    Program received signal SIGSEGV, Segmentation fault.
    0x000000000041519d in SC_ShmLoadBankInfo () at SCPubFunc.pc:102
    SC_ShmGetStru(g_stConf.iShmID, MODE_BANK_ARRAY, i, (void *)&pstBank);
    102 pstBank->iBankID = iBankID;
    voici la methode qui attribue l'adresse 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
    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
    int SC_ShmGetStru(int iShmID, int iMode, int iID, void **pAddr)
    {
        int i, iOffset, iStruSize;
        ST_SC_BankInfo *pstBank = NULL;
        ST_SC_SvcInfo *pstSvc = NULL;
        void *pBase;
     
        /* get shm base addr (attach) */
        if ((int)(*pBase = (void*)shmat(iShmID, (void*)0, 0)) == -1)
        {
            sprintf(g_caMsg, "[Fail] ShmGetStru, attach shm");
            ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
            return -1;
        }
     
        switch (iMode)
        {
        case MODE_CONFIG:
            *pAddr = (ST_SC_Config *) pBase;
            return 0;
        case MODE_BANK_ARRAY:
            iOffset = sizeof(ST_SC_Config);
            iStruSize = sizeof(ST_SC_BankInfo);
            if (iID > BANK_NUM)
            {
                sprintf(g_caMsg, "[Fail] ShmGetStru, illegal bank array %d", iID);
                ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
                shmdt(pBase);
                return -1;
            }
            *pAddr = (ST_SC_BankInfo *) (pBase + iOffset + sizeof(ST_SC_BankInfo) * iID);
            return 0;
        case MODE_BANK_VALUE:
            iOffset = sizeof(ST_SC_Config);
            iStruSize = sizeof(ST_SC_BankInfo);
            for (i=0; i<BANK_NUM; i++)
            {
                pstBank = (ST_SC_BankInfo *) (pBase + iOffset + iStruSize * i);
                if (pstBank->iBankID == iID)
                {
                    *pAddr = pstBank;
                    return 0;
                }
            }
            sprintf(g_caMsg, "[Fail] ShmGetStru, bank value not found:%d", iID);
            ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
            shmdt(pBase);
            return -1;
        case MODE_SVC_ARRAY:
            if (iID > g_stConf.iSvcNum)
            {
                sprintf(g_caMsg, "[Fail] ShmGetStru, illegal svc array %d", iID);
                ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
                shmdt(pBase);
                return -1;
            }
            iOffset = sizeof(ST_SC_Config) + sizeof(ST_SC_BankInfo) * BANK_NUM;
            iStruSize = sizeof(ST_SC_SvcInfo);
            pstSvc = (ST_SC_SvcInfo *) (pBase + iOffset + iStruSize * iID);
            *pAddr = pstSvc;
            break;
        case MODE_SVC_VALUE:
            iOffset = sizeof(ST_SC_Config) + sizeof(ST_SC_BankInfo) * BANK_NUM;
            iStruSize = sizeof(ST_SC_SvcInfo);
            for (i=0; i<g_stConf.iSvcNum; i++)
            {
                pstSvc = (ST_SC_SvcInfo *) (pBase + iOffset + iStruSize * i);
                if (pstSvc->iSvcID == iID)
                {
                    *pAddr = pstSvc;
                    return 0;
                }
            }
            sprintf(g_caMsg, "[Fail] ShmGetStru, svc value not found:%d", iID);
            ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
            shmdt(pBase);
            return -1;
        default:
            sprintf(g_caMsg, "[Fail] ShmGetStru, invalide Mode:%d", iMode);
            ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
            shmdt(pBase);
            return -1;
        }
     
        return 0;
    }
    La partie du code où le programme plante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SC_ShmGetStru(g_stConf.iShmID, MODE_BANK_ARRAY, i, (void *)&pstBank);
    pstBank->iBankID = iBankID;
    strcpy(pstBank->caDBUsr, caDBUsr);
    strcpy(pstBank->caBankName, caBankName);
    strcpy(pstBank->caTax, caTax);
    strcpy(pstBank->caBin, caBin);
    SC_ShmDettach(pstBank);
    Merci pour votre aide.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,



    j'ai une methode en C qui attribue une adresse memoire à une structure de donnees qu'elle a reçu en parametre
    Ce n'est pas possible en C.
    Tu peux déplacer (copie + suppression de l'originale) ou copier une structure mais pas lui "attribuer une adresse mémoire".

    Pour ton segfault, je suppose que tu essaye de copier ta structure en oubliant de faire un malloc ?

    J'ai vite survolé ton code mais sans les balises codes, il est illisible.

  3. #3
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 14
    Par défaut
    je viens de mettre les balises. Ce que j'aimerais savoir pourquoi cela plante a ce niveau. Hors je souligne ce code marchait correctement, et depuis que nous sommes passé en 64 bits, nous rencontrons ce probleme.

    Program received signal SIGSEGV, Segmentation fault.
    0x000000000041519d in SC_ShmLoadBankInfo () at SCPubFunc.pc:102
    SC_ShmGetStru(g_stConf.iShmID, MODE_BANK_ARRAY, i, (void *)&pstBank);
    102 pstBank->iBankID = iBankID;


    voici la methode qui attribue l'adresse 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
    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
     
    int SC_ShmGetStru(int iShmID, int iMode, int iID, void **pAddr)
    {
    int i, iOffset, iStruSize;
    ST_SC_BankInfo *pstBank = NULL;
    ST_SC_SvcInfo *pstSvc = NULL;
    void *pBase;
     
    /* get shm base addr (attach) */
    if ((int)(*pBase = (void*)shmat(iShmID, (void*)0, 0)) == -1)
    {
    sprintf(g_caMsg, "[Fail] ShmGetStru, attach shm");
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    return -1;
    }
     
    switch (iMode)
    {
    case MODE_CONFIG:
    *pAddr = (ST_SC_Config *) pBase;
    return 0;
    case MODE_BANK_ARRAY:
    iOffset = sizeof(ST_SC_Config);
    iStruSize = sizeof(ST_SC_BankInfo);
    if (iID > BANK_NUM)
    {
    sprintf(g_caMsg, "[Fail] ShmGetStru, illegal bank array %d", iID);
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    shmdt(pBase);
    return -1;
    }
    *pAddr = (ST_SC_BankInfo *) (pBase + iOffset + sizeof(ST_SC_BankInfo) * iID);
    return 0;
    case MODE_BANK_VALUE:
    iOffset = sizeof(ST_SC_Config);
    iStruSize = sizeof(ST_SC_BankInfo);
    for (i=0; i<BANK_NUM; i++)
    {
    pstBank = (ST_SC_BankInfo *) (pBase + iOffset + iStruSize * i);
    if (pstBank->iBankID == iID)
    {
    *pAddr = pstBank;
    return 0;
    }
    }
    sprintf(g_caMsg, "[Fail] ShmGetStru, bank value not found:%d", iID);
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    shmdt(pBase);
    return -1;
    case MODE_SVC_ARRAY:
    if (iID > g_stConf.iSvcNum)
    {
    sprintf(g_caMsg, "[Fail] ShmGetStru, illegal svc array %d", iID);
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    shmdt(pBase);
    return -1;
    }
    iOffset = sizeof(ST_SC_Config) + sizeof(ST_SC_BankInfo) * BANK_NUM;
    iStruSize = sizeof(ST_SC_SvcInfo);
    pstSvc = (ST_SC_SvcInfo *) (pBase + iOffset + iStruSize * iID);
    *pAddr = pstSvc;
    break;
    case MODE_SVC_VALUE:
    iOffset = sizeof(ST_SC_Config) + sizeof(ST_SC_BankInfo) * BANK_NUM;
    iStruSize = sizeof(ST_SC_SvcInfo);
    for (i=0; i<g_stConf.iSvcNum; i++)
    {
    pstSvc = (ST_SC_SvcInfo *) (pBase + iOffset + iStruSize * i);
    if (pstSvc->iSvcID == iID)
    {
    *pAddr = pstSvc;
    return 0;
    }
    }
    sprintf(g_caMsg, "[Fail] ShmGetStru, svc value not found:%d", iID);
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    shmdt(pBase);
    return -1;
    default:
    sprintf(g_caMsg, "[Fail] ShmGetStru, invalide Mode:%d", iMode);
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    shmdt(pBase);
    return -1;
    }
     
    return 0;
    }
    La partie du code où le programme plante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SC_ShmGetStru(g_stConf.iShmID, MODE_BANK_ARRAY, i, (void *)&pstBank);
    pstBank->iBankID = iBankID;
    strcpy(pstBank->caDBUsr, caDBUsr);
    strcpy(pstBank->caBankName, caBankName);
    strcpy(pstBank->caTax, caTax);
    strcpy(pstBank->caBin, caBin);
    SC_ShmDettach(pstBank);
    ......

    Merci pour votre aide.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pour mettre la balise code il faut faire comme sur la petite image :
    avec des crochets.

    EDIT : le temps de poster vous avez trouver comment mettre la balise code^^

    Peux-tu mettre un petit commentaire à la ligne exacte où le programme plante?

    Sinon, soit le pointeur sur ta structure ne pointe pas sur une zone allouée soit les pointeurs sur char contenu dans ta structure ne pointent pas sur une zone alloué assez grande.
    Si la taille des chaînes de caractère varie, essaye plutôt d'utiliser strncpy.
    Sinon un coup de Valgrind t'aidera peut-être.

  5. #5
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 14
    Par défaut
    voici ou le programme plante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SC_ShmGetStru(g_stConf.iShmID, MODE_BANK_ARRAY, i, (void *)&pstBank);
    pstBank->iBankID = iBankID;  /* voici ou le prog plante*/
    strcpy(pstBank->caDBUsr, caDBUsr);
    strcpy(pstBank->caBankName, caBankName);
    strcpy(pstBank->caTax, caTax);
    strcpy(pstBank->caBin, caBin);
    SC_ShmDettach(pstBank);
    ......

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    pstBank ne pointe donc pas dans une zone mémoire allouée.

    SC_ShmGetStru doit donc ne pas donner une valeur correcte à pstBank.
    Essayez de voir quelle affectation conduit à une erreur erronée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *pAddr = (ST_SC_BankInfo *) (pBase + iOffset + sizeof(ST_SC_BankInfo) * iID);
    Vous avez l'air de faire pas mal de calculs, attention, la taille d'une structure est égale ou supérieur à la somme des tailles de se qu'elle contient.

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    J'ai l'impression que troumar retourne une adresse pointant directement dans la mémoire partagée, alors qu'il fait un shmdt dans la fonction.
    Cela n'est-il pas équivalent à ce genre de bêtise?
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void* f()
    {
    	void *p = malloc(1);
    	free(p);
    	return p;
    }
    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.

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    J'ai l'impression que troumar retourne une adresse pointant directement dans la mémoire partagée, alors qu'il fait un shmdt dans la fonction.
    Cela n'est-il pas équivalent à ce genre de bêtise?
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void* f()
    {
    	void *p = malloc(1);
    	free(p);
    	return p;
    }
    Il ne fait le shmdt que s'il a une erreur et dans ce cas, il devrait avoir un message d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sprintf(g_caMsg, "[Fail] ShmGetStru, illegal bank array %d", iID);
    ErrLog(TRACE_LEVEL5, g_caMsg, RPT_TO_LOG, 0, 0);
    shmdt(pBase);

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Ah OK.
    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.

  10. #10
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Le plantage a lieu avec pour case MODE_BANK_ARRAY. Le code exécuté dans ce cas est, en supposant qu'aucune des erreurs détectées par le code ne se produise, et en supprimant des cast abusifs et inutiles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int SC_ShmGetStru(int iShmID, int iMode, int iID, void **pAddr) //iMode ==MODE_BANK_ARRAY
    {
       int i, iOffset, iStruSize;
       ST_SC_BankInfo *pstBank = NULL;
       ST_SC_SvcInfo *pstSvc = NULL;
       void *pBase;
     
       pBase = shmat(iShmID, NULL, 0);
       iOffset = sizeof(ST_SC_Config);
       iStruSize = sizeof(ST_SC_BankInfo);
       *pAddr = pBase + iOffset + sizeof(ST_SC_BankInfo) * iID;
       return 0;
    }
    Je suis étonné du calcul de pBase + iOffset + sizeof(ST_SC_BankInfo) * iID avec un pbase de type void* : la taille de l'objet pointé est inconnue.
    Vu la présence d'un sizeof dans ce calcul, j'opterai pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     *pAddr = (char*)pBase + iOffset + sizeof(ST_SC_BankInfo) * iID;
    Quand au if :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (pBase = shmat(iShmID, NULL, 0)) == (void*)-1) ...
    me semble logique

Discussions similaires

  1. memoire partagée : pointeur
    Par samplaid dans le forum C
    Réponses: 5
    Dernier message: 23/11/2007, 19h36
  2. pointeurs dans une memoire partagée
    Par iznogoud36 dans le forum C
    Réponses: 15
    Dernier message: 13/06/2007, 17h05
  3. segment de memoire partagé en C
    Par thierry_b dans le forum C
    Réponses: 2
    Dernier message: 29/11/2005, 21h30
  4. [segment de memoire partagée]
    Par pitit777 dans le forum C
    Réponses: 4
    Dernier message: 26/11/2005, 14h47
  5. Réponses: 13
    Dernier message: 05/05/2004, 19h09

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