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 :

[Débutant] Debugage Mini-Purify (Malloc)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 44
    Par défaut [Débutant] Debugage Mini-Purify (Malloc)
    Bonsoir,

    J'ai quelques soucis de gestion dynamique de la mémoire, mini-purify les a détecté mais je n'arrive pas à les résoudre.

    j'ai un programme test, un .h de déclarations des fonctions et un .c où sont définies ces fonctions.

    Il s'agit de calculer les transformées en cosinus discrète des coefficients d'une matrice test donnée

    Voici mon .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef DCT__H
    #define DCT__H
     
    typedef struct {
        int** coeff;
        int lignes;
        int colonnes;
    } matrice;
     
    void initialiser_matrice(matrice m);
    int heaviside(int u);
    int corps_dct(matrice m,int taille,int x,int y,int u,int v);
    int coeff_dct(matrice m, int u, int v);
    #endif
    Mon .c
    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
     
    #include "DCT.h"
    #define PI 3.14
     
    int heaviside(int u){
    	return (u == 0);
    }
     
    void initialiser_matrice(matrice m){
    	m.coeff=0;
    	m.lignes=0;
    	m.colonnes=0;
    }
     
    int corps_dct(matrice m,int taille,int i,int j,int u,int v){
    	int resultat;
    	taille= m.lignes*m.colonnes;
    	resultat=(m.coeff[i][j])*cos(((2*i+1)*PI*u)/(2*taille))*cos(((2*j+1)*PI*v)/(2*taille));
     
    	return resultat;
    }
     
    int coeff_dct(matrice m, int u, int v){
    	int taille;
    	int i, j, temp;
    	taille= m.lignes*m.colonnes;
    	temp=0;
    	/*Facteurs de la double sommation*/
    	int a=(2/taille)*(1/sqrt(2));
    	int b=heaviside(u)+heaviside(v);
    	int c= pow(a,b);
    	/*Double sommation*/
    	for (i=0; i<=taille-1; i++){
    		for(j=0; j<=taille-1; j++){
    			temp += corps_dct(m, taille, i, j, u, v);
    		}
    	}
     
    	/*Resultat*/
    	temp=temp*c;
    	return temp;
    }
    et mon programme de test
    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
     
    int main(){
    	matrice t;
    	initialiser_matrice(t);
    	int i, j;
     
    	/*Allocation de mémoire*/
    	t.coeff=malloc(8*sizeof(int*));
    	for (i=0; i<=8; i++) t.coeff[i]=malloc(8*sizeof(int));
     
    	if (t.coeff != NULL){
    		t.lignes=8;
    		t.colonnes=8;
     
    		t.coeff[0][0]=139;
    		t.coeff[0][1]=144;
    		t.coeff[0][2]=149;
    		t.coeff[0][3]=153;
    		t.coeff[0][4]=155;
    		t.coeff[0][5]=155;
    		t.coeff[0][6]=155;
    		t.coeff[0][7]=155;
    		t.coeff[1][0]=144;
    		t.coeff[1][1]=151;
    		t.coeff[1][2]=153;
    		t.coeff[1][3]=156;
                    ...
    		t.coeff[7][4]=163;
    		t.coeff[7][5]=158;
    		t.coeff[7][6]=158;
    		t.coeff[7][7]=158;
     
    		for (i=0; i<=7; i++){
    			for (j=0; j<=7; j++) printf("%d ", coeff_dct(t, i, j));
    			printf("\n");
    		}
     
    		for (i=0; i<=8; i++) free(t.coeff[i]);
    		free(t.coeff);
    	}
    	return EXIT_SUCCESS;
    }
    Purify me sort que j'ai 371erreurs dont 368 ABR: Array bounds read et 0 fuite mémoire.
    les ABR sont localisées dans la définition de la fonction corps_dct et coeff_dct respectivement, au moment d'appeler les valeurs m.coeff[i][j] et au moment d'appeler corps_dct... donc la même erreur en gros.
    Et dans mon programme de test, au moment d'appeler coeff_dct.. toujours la même erreur il me semble.

    Il doit yavoir un soucis dans mes malloc!
    J'attend vos réponses

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    1) Dans la fonction initialiser_matrice, tu fais une copie de la matrice et tu initialises donc les valeurs sur elle et non sur celle qui est passée en argument. Il faut passer l'adresse de la matrice :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void initialiser_matrice(matrice *m)
    {
    	m->coeff=0;
    	m->lignes=0;
    	m->colonnes=0;
    }
     
    (...)
     
    initialiser_matrice(&t);

    2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	t.coeff=malloc(8*sizeof(int*));
    	for (i=0; i<=8; i++) t.coeff[i]=malloc(8*sizeof(int));
    Tu réserves 8 pointeurs de pointeurs sur int, mais tu alloues ensuite 9 pointeurs sur int et non 8. Ce qui est susceptible de crasher le programme. Il faut utiliser l'opérateur < et non <=.

    3) Même problème lors de la libération de mémoire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (i=0; i<=8; i++) free(t.coeff[i]);
    Il faut modifier l'opérateur <= par <.

    4) Je ne sais pas comment se calcule le DCT, mais dans la fonction coeff_dct, il y a un truc qui cloche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    taille= m.lignes*m.colonnes;
    (...)
    for (i=0; i<=taille-1; i++){
    	for(j=0; j<=taille-1; j++){
    		temp += corps_dct(m, taille, i, j, u, v);
    	}
    }
    Dans la fonction corps_dct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    resultat=(m.coeff[i][j])*cos(((2.0*i+1.0)*PI*u)/(2.0*taille))*cos(((2.0*j+1.0)*PI*v)/(2.0*taille));
    vu que i et j ne sont pas compris entre 0 et 7 inclus mais entre 0 et taille (=8*8), ça crashe donc le programme.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 44
    Par défaut
    Citation Envoyé par jeroman Voir le message
    1) Dans la fonction initialiser_matrice, tu fais une copie de la matrice et tu initialises donc les valeurs sur elle et non sur celle qui est passée en argument. Il faut passer l'adresse de la matrice :
    Je m'étais trompé, ce n'est pas un pointeur vers matrice mais bien une variabe de type matrice

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void initialiser_matrice(matrice m)
    {
    	m.coeff=0;
    	m.lignes=0;
    	m.colonnes=0;
    }
     
    (...)
     
    initialiser_matrice(t);

    2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	t.coeff=malloc(8*sizeof(int*));
    	for (i=0; i<=7; i++) t.coeff[i]=malloc(8*sizeof(int));
    Tu réserves 8 pointeurs de pointeurs sur int, mais tu alloues ensuite 9 pointeurs sur int et non 8. Ce qui est susceptible de crasher le programme. Il faut utiliser l'opérateur < et non <=.

    3) Même problème lors de la libération de mémoire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (i=0; i<=7; i++) free(t.coeff[i]);
    Il faut modifier l'opérateur <= par <.

    4) Je ne sais pas comment se calcule le DCT, mais dans la fonction coeff_dct, il y a un truc qui cloche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    taille= m.lignes*m.colonnes;
    (...)
    for (i=0; i<=m.lignes-1; i++){
    	for(j=0; j<=m.colonnes-1; j++){
    		temp += corps_dct(m, taille, i, j, u, v);
    	}
    }
    Dans la fonction corps_dct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    resultat=(m.coeff[i][j])*cos(((2.0*i+1.0)*PI*u)/(2.0*taille))*cos(((2.0*j+1.0)*PI*v)/(2.0*taille));
    vu que i et j ne sont pas compris entre 0 et 7 inclus mais entre 0 et taille (=8*8), ça crashe donc le programme.
    ------------------------------
    J'ai réglé mes petites erreurs, qui n'en étaient pas unes, puisque j'avais déjà corrigé la version de chez moi, j'ai posté la version non corrigée par mégarde. Donc bref, mes soucis sont toujours les mêmes!
    Au sujet du calcul de la fonction coeff_dct... je vous mets un aperçu de la formule mathématique du calculs des coefficients de la DCT.

    Nom : dct.jpg
Affichages : 70
Taille : 31,7 Ko

    Merci et bonne soirée,

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    J'ai réglé mes petites erreurs, qui n'en étaient pas unes, puisque j'avais déjà corrigé la version de chez moi, j'ai posté la version non corrigée par mégarde. Donc bref, mes soucis sont toujours les mêmes!
    Dans ce cas, la première chose à faire est de reposter ton code corrigé, car c'est impossible de savoir ce que tu as modifié ou non et ça va être difficile de t'aiguiller.

    Ensuite :

    1) D'après la formule que tu as posté, il y a effectivement des problèmes avec ton algorithme car ton calcul n'est pas cohérent avec l'équation.

    a) Par exemple, lorsque tu as un calcul du genre :
    A*(B) puissance X , cela ne correspond pas à (A*B) puissance X.
    Le (B) correspond à ce qui est entre parenthèses au début de l'équation de la DCT :
    A=2.0/N
    B=1.0/sqrt(2.0)
    Or, tu calcules comme si tout était entre parenthèses, comme si on avait (A*B) puissance X :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a=(2/taille)*(1/sqrt(2));
    int b=heaviside(u)+heaviside(v);
    int c= pow(a,b);
    b) Par rapport au calcul juste au-dessus, tu utilises taille (qui vaut 64) au lieu de 8.

    2) De plus, tu calcules tout en entier, ce qui aggrave la chose. Il faut calculer en double, puis arrondir à l'entier (si j'ai bien compris le système DCT ?) une fois que tu envoies le résultat de l'équation complètement calculée.

    3) Lorsque tu accèdes à ta matrice de pixels, il faut faire attention à l'ordre des indices. En C, il y a un ordre précis.
    Je suppose que dans ta matrice, il s'agit de la forme : coeff[ligne][colonne] ? Or, dans corps_dct, tu inverses i et j dans coeff.

    4) Tu envoie la variable taille dans corps_dct pour la recalculer juste après, ce qui n'est pas cohérent. De plus, pour le calcul, on n'a pas besoin de cette valeur. Tu peux donc supprimer cette variable de la liste des arguments. ^^

    5) Ne pas oublier de rajouter le suffixe .0 aux nombres à virgule. Ca évite bien des soucis et des bugs.

    6) Pour calculer une DCT, il faut une matrice d'une longueur égale à sa hauteur (si j'ai bien tout compris), ce qui correspond en tout cas à N*N dans l'équation qui est donnée en pièce jointe. Il y a donc moyen d'optimiser le code.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    44
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 44
    Par défaut
    Bonjour, j'ai suivi vos instructions.. maintenant j'ai une matrice 8*8 qui s'affiche.. mais c'est pas les bonnes valeurs, je suspect une erreur de manipulation des double et des int..
    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
     
    #define PI 3,14159265
     
    int heaviside(int u){
    	return (u == 0);
    }
     
    void initialiser_matrice(matrice m){
    	m.coeff=0;
    	m.hauteur=0;
    	m.largeur=0;
    }
     
    int corps_dct(matrice m, int i,int j,double u,double v){
    	int resultat=0, taille;
    	double a1=0, a2=0, a3=0, a4=0, b1=0, b2=0, b3=0, b4=0;
            taille= m.hauteur;
     
            a1=(2.0*i+1.0)*PI*u;
    	a2=2.0*taille;
    	b1=(2.0*j+1.0)*PI*v;
    	b2=2.0*taille;
    	a3=a1/a2;
    	b3=b1/b2;
    	a4=cos(a3);
    	b4=cos(b3);
    	resultat=(m.coeff[j][i])*a4*b4;
     
    	return resultat;
    }
     
    int coeff_dct(matrice m, double u, double v){
    	int taille;
    	int i, j, temp=0;
    	taille= m.hauteur;
    	/*Facteurs de la double sommation*/
    	double a=2.0/taille;
    	double b=1.0/sqrt(2.0);
    	double c=heaviside(u)+heaviside(v);
    	double d= pow(b,c);
    	/*Double sommation*/
    	for (i=0; i<=m.hauteur-1; i++){
     	        for(j=0; j<=m.largeur-1; j++){
    			temp += corps_dct(m, i, j, u, v);
    		}
    	}
    	temp=a*d*temp;
    	return temp;
    }

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Salut,

    J'ai corrigé ton code. Fais un test pour vérifier si les valeurs générées sont bonnes.

    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
    #define PI 3.14159265 /* un point, pas une virgule !  */
     
    typedef struct
    {
        int** coeff;
        int hauteur;
        int largeur;
    } matrice;
     
    int heaviside(int u){
    	return (u != 0); /* != */
    }
     
     /* faut passer l'adresse de la matrice sinon elle est modifiée seulement en local */
    void initialiser_matrice(matrice *m){
    	m->coeff=NULL;
    	m->hauteur=0;
    	m->largeur=0;
    }
     
    /* la fonction doit renvoyer un type double */
    double corps_dct(matrice m, int i,int j,double u,double v){
    	double resultat=0.0; /* resultat doit être de type double */
        int taille;
    	double a1=0.0, a2=0.0, a3=0.0, a4=0.0, b1=0.0, b2=0.0, b3=0.0, b4=0.0;
        taille= m.hauteur;
     
        a1=(2.0*i+1.0)*PI*u;
    	a2=2.0*taille;
    	b1=(2.0*j+1.0)*PI*v;
    	b2=2.0*taille;
    	a3=a1/a2;
    	b3=b1/b2;
    	a4=cos(a3);
    	b4=cos(b3);
    	resultat=(m.coeff[j][i])*a4*b4;
    	return resultat;
    }
     
    int coeff_dct(matrice m, double u, double v){
    	int taille;
    	int i, j;
        double temp=0.0; /* temp doit être de type double */
    	taille= m.hauteur;
    	/*Facteurs de la double sommation*/
    	double a=2.0/taille;
    	double b=1.0/sqrt(2.0);
    	double c=heaviside(u)+heaviside(v);
    	double d= pow(b,c);
    	/*Double sommation*/
    	for (i=0; i<=m.hauteur-1; i++){
     	        for(j=0; j<=m.largeur-1; j++){
    			temp += corps_dct(m, i, j, u, v);
    		}
    	}
    	temp=a*d*temp;
    	return temp;
    }
    Corrections :

    1) Dans la fonction heaviside, j'avais oublié de te préciser qu'il y avait aussi un problème. Il faut en fait utiliser l'opérateur != et non ==.
    Si la valeur est différente de zéro, la condition est donc vraie et donc la fonction renvoie 1.
    Si la valeur est égale à zéro, elle n'est donc pas différente de zéro, le résultat du test est donc faux, ce qui renvoie 0.

    2) Dans les fonctions corps_dct et coeff_dct, tu travaillais toujours avec le type entier. Il faut utiliser des double. Par contre, dans la fonction coeff_dct, seul le résultat final doit être renvoyé en entier (si j'ai bien compris le principe de la DCT... (?)).

    3) Dans la fonction initialiser_matrice, tu n'avais toujours pas corrigé le type de l'argument... même si le problème des données fausses ne vient pas de là.
    En passant l'argument par copie, tu ne modifies que l'objet local. Une fois qu'on quitte la fonction, l'objet est perdu. Pour modifier l'objet envoyé à la fonction, il faut lui passer son adresse et travailler dessus.

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

Discussions similaires

  1. Problème [gros débutant!] avec malloc
    Par Nival dans le forum Débuter
    Réponses: 5
    Dernier message: 13/03/2009, 17h05
  2. Réponses: 2
    Dernier message: 30/12/2006, 19h21
  3. Réponses: 10
    Dernier message: 26/10/2006, 12h35
  4. mini jeu en construction (débutant)
    Par samy100 dans le forum C
    Réponses: 45
    Dernier message: 23/04/2006, 23h36
  5. Réponses: 6
    Dernier message: 06/12/2005, 09h41

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