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 :

Violation d'accès louche


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut Violation d'accès louche
    Bonjour à tous, je travaille sur un projet qui comprend une fonction qui permet de découper le centre d'une image passée en paramètre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    prototype :
    float *retailler(int PetitX, int PetitY, int GrandX, int Grand Y, MIL_ID *Buffer);
    Je passe en paramètre : les dimensions de l'image contenue dans buffer ainsi que les dimensions souhaitées.

    Dans mon programme je suis amené à appeler souvent cette fonction (elle est dans une boucle. Pour faire simple : J'acquiert une image provenant d'une caméra, je découpe son centre, puis j'affiche le centre et je recommence).

    Or, au bout de 3 fois, J'obtiens une erreur "Violation d'accès (0xc0000005) à l'adresse ....." de la part de Dr Watson (le pc sur lequel je travaille est un PII300 avec NT4)....

    J'ai donc décortiqué le code de ma petite fonction, et je me suis aperçu que la ligne qui provoquait ce message etait en fait un malloc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pixel = (unsigned char*)malloc(GrandX*GrandY*sizeof(unsigned char));
    Je tiens à préciser que je le libère à la fin de ma fonction. En fait, ça marche... 2 fois seulement.

    Si vous avez une idée de la cause de cette erreur, je suis preneur !

    Merci beaucoup !


    PS : J'ai en fait un paquet de problèmes très bizarres. Le PC a l'air hanté
    A vrai dire, juste après le malloc, j'ai la ligne de code suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pixel = (unsigned char*)Buffer;
    L'adresse que le malloc a renvoyé ne me sert donc à rien ! vous trouvez ça stupide ? ouais... moi aussi, mais si je mets pas le malloc, le programme ne fonctionne plus... (pas d'erreur, mais il ne m'affiche pas mon image).

    Je pense que les bibliothèques fournies avec la carte sur laquelle est branchée la caméra sont un peu ... pas bien...

  2. #2
    Membre chevronné
    Avatar de joellel
    Profil pro
    Inscrit en
    Février 2003
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2003
    Messages : 234
    Par défaut
    Comment déclares tu pixel?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    comme ça :

    unsigned char *pixel;

  4. #4
    Membre chevronné
    Avatar de joellel
    Profil pro
    Inscrit en
    Février 2003
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2003
    Messages : 234
    Par défaut
    Envoie ton code!

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    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
     
    /******************************************************************************/
    /*                   			retailler l'image                     */
    /*----------------------------------------------------------------------------*/
    /*    Fonction  : Fonction qui découpe l'image aux dimensions PetitX*PetitY   */
    /*									      */
    /*    Entrées : PetitX => Longueur de l'image après découpage			      */
    /*              PetitY => Largeur de l'image après découpage			      */
    /*              GrandX => Largeur de l'image avant découpage			      */
    /*              GrandY => Largeur de l'image avant découpage			      */
    /*              buf    => Tampon contenant l'image au format MIL_ID   		      */
    /*    Sortie :  Pointeur (float) vers l'adresse contenant l'image   			      */
    /*                                                                            */
    /******************************************************************************/
     
    float *retailler(int PetitX, int PetitY, int GrandX, int GrandY, MIL_ID *buf)
    {
     
    int deltaX;		//'Marges' quand la petite image est centrée sur la grande
    int deltaY;
     
    int i,j; 		//Indices de boucle
     
    float *pixelfloat;		  			//Pointeur pour l'image en float
    unsigned char *pixel,*pixel_i;   //Pointeur pour l'image en char
     
     
    //Allocation de la mémoire pour les deux images
    pixel = (unsigned char *)malloc(GrandX*GrandY);	//Cette ligne fait planter le prog !
    pixel_i = pixel;             //pixel_i pour garder l'adresse initiale
    pixelfloat = (float*)malloc(PetitX*PetitY*sizeof(float));
     
    //on place la pointeur de char sur l'adresse de début de l'image en Mil_id
    pixel = (unsigned char *)buf;   
     
    //Calcul des marges
    deltaX = (GrandX-PetitX)/2;
    deltaY = (GrandY-PetitY)/2;
     
    for(j=0;j<GrandY;j++)
    {
        	for(i=0;i<GrandX;i++)
          {  //Si le pixel lu dans la grande image n'est pas dans les marges
          	if(i>=deltaX && i<(PetitX + deltaX) && j>=deltaY && j<(PetitY + deltaY))
             {
             	 //On l'ajoute à la petite image
                 *pixelfloat = (float)*pixel;
                 //On passe au pixel suivant sur la petite image
                 pixelfloat++;
             }
             //Dans tous les cas, on doit lire le pixel suivant sur la grande image
             pixel++;
          }
    }
     
    //libération mémoire
    free(pixel_i);
    //Renvoi de l'image en 512*512 float
    return(pixelfloat - PetitX*PetitY);
    }

  6. #6
    Membre chevronné
    Avatar de joellel
    Profil pro
    Inscrit en
    Février 2003
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2003
    Messages : 234
    Par défaut
    Pas évident...
    As tu regardé les valeurs de GrandX et GrandY avant le malloc??
    Teste aussi à chaque fois le code retour de ton malloc.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    C'est moi qui passe ces valeurs, elles valent toujours 768 et 576.

    Je suis en train de chercher , c'est hallucinant...

  8. #8
    Expert confirmé

    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 : 45
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Et que valent PetitX et PetitY?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pixelfloat = (float*)malloc(PetitX*PetitY*sizeof(float));
    - Enlève le cast du malloc et fait un test sur le retour du malloc.

    - Ensuite, utilise la même méthode pour le malloc pixel en utilisant un autre pointeur pour se souvenir du retour du malloc (pour ton retour)

    Est-ce que tu peux aussi montrer la boucle qui appelle cette fonction?
    Jc

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    - Enlève le cast du malloc et fait un test sur le retour du malloc.
    J'ai dejà fait, ça change rien.

    - Ensuite, utilise la même méthode pour le malloc pixel en utilisant un autre pointeur pour se souvenir du retour du malloc (pour ton retour)
    J'y vais

    Est-ce que tu peux aussi montrer la boucle qui appelle cette fonction?
    Là ça va être plus compliqué... Le code est long (pour cette partie y a environ 100 lignes je pense). C'est un bête do/while : je fais appel à ma fonction au début, elle reçoit en paramètre directement le tampon fourni la carte (Buffer), et une fois qu'elle renvoie sa valeur en float, je n'y touche plus. Les seuls éléments qui pourraient influer, ce sont d'autres malloc (mais qui fonctionnent bien!) dans la boucle, sachant que je fais absolument tous les free() avant la fi de la boucle. (sinon, on a rapidement fait de remplir la memoire ).

  10. #10
    Expert confirmé

    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 : 45
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par fearyourself
    Et que valent PetitX et PetitY?

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    pardon, c'est pareil que pour grand, c'est 512*512, toujours.

    Sinon, je viens de regarder les adresses renvoyées successivement par le malloc.

    Lors de la première boucle, j'ai 0x23e00a0, lors de la seconde, j'ai 0x283009c.
    C'est toujours la même chose, à chaque fois que je le lance.

    Pour moi, logiquement, lors de la deuxième boucle il pourrait reprendre l'adresse 0x23e00a0 vu que je la libère ?

    Mais non, il va chercher 4Mo plus loin environ dans la memoire... Mon doute est le suivant : Peut être que le 3ème coup, il veut encore allouer 4Mo plus loin, mais qu'il a pas le droit !

    Vous en pensez quoi ?

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 159
    Par défaut
    Je vois qu'il y a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pixel = (unsigned char *)buf;   
     
    ....         pixel++;
    Si pixel adresse une zone de memoire non allouée dynamiquent alors le prochain appel à
    peut generer un access violation.
    Attention aux debordement

  13. #13
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Tu demandes quand même 1 048 576 octets à chaque fois, c'est pas mal.
    C'est quoi ce retour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return(pixelfloat - PetitX*PetitY);
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  14. #14
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,

    Je ne vois pas pourquoi tu prends la peine de réserver de la place pour pixel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pixel = (unsigned char *)malloc(GrandX*GrandY);	//Cette ligne fait planter le prog !
    Puisque juste après tu lui affectes une valeur dont tu disposes, avec un simple cast:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //on place la pointeur de char sur l'adresse de début de l'image en Mil_id
    pixel = (unsigned char *)buf;
    Tu n'as absolument pas besoin de faire cette réservation/libération de mémoire.

    Par contre, ça ne fait pas partie du code que tu montres, mais j'espère que tu libères la mémoire réservée pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pixelfloat = (float*)malloc(PetitX*PetitY*sizeof(float));
    sinon, énorme fuite de mémoire (qui explique peut-être ton problème ?).

    D'ailleurs, et curieusement, tu prends la précaution de sauver ton pixel, mais pas pixelfloat, dont tu as besoin pour retourner la valeur (d'accord, un petit calcul le restore, mais bon...).

    Comme manifestement la taille de ces buffers ne change jamais, tu pourrais certainement te contenter de les réserver une seule fois, au début du traitement.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    Citation Envoyé par Trap D
    Tu demandes quand même 1 048 576 octets à chaque fois, c'est pas mal.
    C'est quoi ce retour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return(pixelfloat - PetitX*PetitY);
    Valeur initiale de l'adresse ... c'était pour éviter de déclarer un autre pointeur, en fait je tatonne et j essaie plein de trucs ..

  16. #16
    Expert confirmé

    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 : 45
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Ok je viens de tester ton code avec un grand buffer :


    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
    int main()
    {
    float *tmp;
    char buf[4000000];
    int i;
     
    for(i=0;i<500;i++)
    {
    tmp = retailler(512,512,768,576,buf);
     
    free(tmp);
    }
     
    return 0;
    }
    Il fonctionne correctement, à mon avis, tu fais un débordement mémoire quelque part.

    - Es-tu sûr de la bonne allocation du paramètre buf?

    - Est-ce que tu géres bien le retour de cette fonction?

    Bien que plus de 100 lignes, voir la boucle serait pratique quand même...

    Jc

  17. #17
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Citation Envoyé par BenjaminLustrement
    Valeur initiale de l'adresse ... c'était pour éviter de déclarer un autre pointeur, en fait je tatonne et j essaie plein de trucs ..
    Là c'est du grand n'importe quoi, tu renvoies une adresse quelque part dans la mémoire, ça plante forcément si tu fais un free dessus après.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  18. #18
    Expert confirmé

    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 : 45
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par Trap D
    Là c'est du grand n'importe quoi, tu renvoies une adresse quelque part dans la mémoire, ça plante forcément si tu fais un free dessus après.
    Je pensais aussi dire ça, mais son calcul me semble juste, il retombe au début... Vu les paramètres passés etc.

    J'avoue n'avoir pas poussé le calcul trop loin et à ce que j'ai compris, il a [EDIT]corrigé et maintenant[/EDIT] fait la même chose qu'avec le malloc pour pixel.

    Jc

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    Je ne vois pas pourquoi tu prends la peine de réserver de la place pour pixel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pixel = (unsigned char *)malloc(GrandX*GrandY);	//Cette ligne fait planter le prog !
    Puisque juste après tu lui affectes une valeur dont tu disposes, avec un simple cast:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //on place la pointeur de char sur l'adresse de début de l'image en Mil_id
    pixel = (unsigned char *)buf;
    Tu n'as absolument pas besoin de faire cette réservation/libération de mémoire.
    Oui, je sais, c'est ce que je disais à la fin de mon premier post. Mais si je fais pas ça, je ne visualise plus mon image (la fenetre reste toute noire). On va chercher à joindre quelqu'un de spécialisé dans la carte qu'on utilise et dans la librairies pour savoir s'il n a pas connaissance de bugs.

    Par contre, ça ne fait pas partie du code que tu montres, mais j'espère que tu libères la mémoire réservée pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pixelfloat = (float*)malloc(PetitX*PetitY*sizeof(float));
    sinon, énorme fuite de mémoire (qui explique peut-être ton problème ?).
    Nan, c'est bon, à chaque tour, il a droit à son petit free();

    Comme manifestement la taille de ces buffers ne change jamais, tu pourrais certainement te contenter de les réserver une seule fois, au début du traitement
    C'est une idée, je vais essayer .. de toutes manières je m'en fiche, puisqu'il me sert à rien, sauf à pas planter plus loin ....

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 79
    Par défaut
    Citation Envoyé par fearyourself
    Je pensais aussi dire ça, mais son calcul me semble juste, il retombe au début... Vu les paramètres passés etc.

    J'avoue n'avoir pas poussé le calcul trop loin et à ce que j'ai compris, il a [EDIT]corrigé et maintenant[/EDIT] fait la même chose qu'avec le malloc pour pixel.

    Jc

    C'est bon, j'ai vérifié avant ... c'est pas tant n'importe quoi que ça. Mais si ça peut vous faire plaisir, je vais m'empresser de mettre un *pixelfloat_i qui garde la valeur d'origine

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. ReportPrinterDialog (QR2) : violation d'accès..
    Par Harry dans le forum Bases de données
    Réponses: 5
    Dernier message: 30/12/2004, 14h04
  2. [XMLDocument] Violation d'accès
    Par xant dans le forum Composants VCL
    Réponses: 8
    Dernier message: 29/09/2004, 15h39
  3. requete / violation d'accès
    Par marie253 dans le forum Bases de données
    Réponses: 4
    Dernier message: 13/08/2004, 13h29
  4. Violation d'acces apres Execute
    Par SegmentationFault dans le forum Connexion aux bases de données
    Réponses: 6
    Dernier message: 10/08/2004, 16h23
  5. Violation d'accès apres Close
    Par SegmentationFault dans le forum Bases de données
    Réponses: 3
    Dernier message: 05/07/2004, 16h46

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