Allocation dynamique d'une matricec

Résolu
djou45 Messages postés 3 Date d'inscription dimanche 6 mars 2005 Statut Membre Dernière intervention 23 octobre 2010 - 22 oct. 2010 à 21:45
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013 - 25 oct. 2010 à 21:10
Bonjour,

Je suis débutant en C, et j'ai un problème avec ce programme ci dessous.
Je pense que le problème est dans cette partie:
matrice init(int nbDeLignes, int nbDeColonnes)
{
  int i, i0, i1;
  int size_Mat = nbDeLignes*nbDeColonnes;
  matrice mat = allouerMatrice();
  mat->nbDeLignes = nbDeLignes;
  mat->nbDeColonnes = nbDeColonnes;
  mat->data = malloc(nbDeLignes*nbDeColonnes*sizeof(int));
/*
 ERROR
*/
  for(i=0; i< size_Mat; ++i)           
           (mat->data)[i] = i;
return mat;
}


quand j'essaye d'initialiser la matrice, le programme s’exécute mais ya une erreur d'accès memoire je pense.
Peut être dans l'allocation de l'espace memoire.


Si quelqu'un peut m'aider



#include<stdio.h>
#include<stdlib.h>

typedef double typeDeDonnees;

typedef struct matrice {
int nbDeLignes ;
int nbDeColonnes ;
typeDeDonnees *data;
} * matrice ;

// allocation de l'espace associe a un pointeur vers matrice
matrice allouerMatrice()
{
return (matrice)malloc(sizeof(struct matrice));
}

// initialisation d'une matrice (et allocation dynamique pour les donnees)
matrice init(int nbDeLignes, int nbDeColonnes)
{
int i, i0, i1;
int size_Mat = nbDeLignes*nbDeColonnes;
matrice mat = allouerMatrice();
mat->nbDeLignes = nbDeLignes;
mat->nbDeColonnes = nbDeColonnes;
mat->data = malloc(nbDeLignes*nbDeColonnes*sizeof(int));
/*
ERROR
*/
for(i=0; i< size_Mat; ++i)
(mat->data)[i] = i;


return mat;
}

void affiche(matrice mat)
{
int i0, i1;
int NBL = mat->nbDeLignes;
int NBC = mat->nbDeColonnes;
printf("Nombre de ligne = %d\n",NBL);
printf("Nombre de colonne = %d\n",NBC);
for (i0=0; i0<NBL; i0++){
printf("\n");
for (i1=0; i1<NBC; i1++)
printf("%d ",mat->data[i0*NBC+i1]);
}
}
//addition de deux matrices
matrice addition(matrice mat1, matrice mat2)
{
if ( mat1==NULL || mat2==NULL)
{ // l'un des deux pointeurs n'est pas alloue
fprintf(stderr,"%s:%d> ERREUR: addition",__FILE__,__LINE__);
exit(EXIT_FAILURE);
}
else
{

}
}

// desallocation des matrices
void liberer(matrice mat)
{
if (mat != NULL)
free(mat->data);
free(mat);
}

int main()
{

matrice mat1 = init(3,5);
matrice mat2 = init(3,5);
matrice mat3 = NULL;
affiche(mat1); // ERROR
liberer(mat1);
system("pause");
/* affiche(mat2);
affiche(mat3);

mat3 = addition(mat1,mat2);
affiche(mat3);*/

liberer(mat1);
liberer(mat2);
liberer(mat3);

return EXIT_SUCCESS;
}

6 réponses

cs_Chouchou182 Messages postés 252 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 25 avril 2011 1
23 oct. 2010 à 00:46
Salut,

Que se passe-t-il si tu modifie la ligne d'allocation par:

mat->data = malloc(nbDeLignes*nbDeColonnes*sizeof(*mat->data));


De manière générale, tu peux écrire
t = malloc(n * sizeof(*t));

n est le nombre d'objets que pourra contenir ton tableau t.

Attention en outre dans ta fonction main, il y a deux appels consécutifs à liberer.

Bonne prog,
3
djou45 Messages postés 3 Date d'inscription dimanche 6 mars 2005 Statut Membre Dernière intervention 23 octobre 2010
23 oct. 2010 à 01:26
Merci,

l'erreur c'est: quand j'exécute le program ça affiche la console d'exécution et les deux premières lignes correctement
printf("Nombre de ligne = %d\n",NBL); 
printf("Nombre de colonne = %d\n",NBC)


ensuite y a deux zéro qui apparient est là erreur Windows ( le programme à cessé de fonctionner).

j'ai même apporté les modification à ça
mat->data = malloc(nbDeLignes*nbDeColonnes*sizeof(*mat->data));

j'ai commenté aussi le deuxième libérer, Mais l'erreur persiste

franchement, je sais pas c'est quoi le problème.

si j'exécute le programme sans cette partie:
/* 
ERROR 
*/ 
for(i=0; i< size_Mat; ++i) 
(mat->data)[i] = i; 

ça m'affiche une matrice avec de grands chiffre et si je met la boucle en modifiant i< 2
for(i=0; i< 2; ++i) 
(mat->data)[i] = i;


le programme marche sans erreur est affiche les deux première valeur à 0 ensuite des grands chiffres alors que normalement les deux premières valeurs sont i=0 ensuite i=1.

et si je met i < 3 ou plus, là erreur system.
0
djou45 Messages postés 3 Date d'inscription dimanche 6 mars 2005 Statut Membre Dernière intervention 23 octobre 2010
23 oct. 2010 à 01:56
Merci Chouchou182,

enfaite ta réponse est presque juste, seulement :
  mat->data = malloc(nbDeLignes*nbDeColonnes*sizeof(double));
  // initialisation de la matrice
  for(i=0; i< size_Mat; ++i)           
           mat->data[i] = sqrt(i);

J'ai mis
sizeof(double)
et ça marche très bien

Merci
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
25 oct. 2010 à 17:55
Salut,

Si ta matrice est destinée à sauvegarder des int je ne vois pas pourquoi tu utiliserai des doubles.
Si on fait du C c'est pour la performance, pas pour mettre des rustines dans le code qui cont par la suite impacter sur la qualité.

Pour ton erreur, ton initialisation des data et mauvaise :

for(i=0; i< size_Mat; ++i)           
           (mat->data)[i] = i;


Tu débutes ta boucle à 1 et tu la termine a nbLignes*nbColonnes + 1.
En gros tu essayes d'écrire dans une zone mémoire qui ne t'appartient pas.

Remplace donc ton ++i par i++ et garde ton code initial.

Shell
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Chouchou182 Messages postés 252 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 25 avril 2011 1
25 oct. 2010 à 18:29
Salut,

Désolé Shell, tu dois être un peu fatigué...

Le programme complet suivant:
#include<stdio.h>

const int MAX =   10;

int
main()
{
  int i;
  for ( i = 0 ; i < MAX ; ++i )
    printf(">  %d\n", i);
  return 0;
}

produit bien (le résultat attendu):
>  0
>  1
>  2
>  3
>  4
>  5
>  6
>  7
>  8
>  9


++i et i++ sont différents en tant qu' expressions . En tant qu'instructions, c'est exactement pareil .

En ce qui concerne l'allocation, je maintiens le conseil donné plus haut et inspiré de la faq de fr.comp.lang.c:
12.2 Comment allouer proprement une variable ?

Le plus portable et le plus simple est de faire ainsi :

var_t * ma_var = malloc(N * sizeof *ma_var);

Si le type de la variable change, l'allocation est toujours
valide. À noter que l'on ne caste pas le retour de malloc()


Enfin, si c'est l'affichage qui plante, regarde la ligne
printf("%d ",mat->data[i0*NBC+i1]);

Est-ce que pour afficher un double, "%d" est ce qu'il convient ? gcc suggère :
warning: format '%d' expects type 'int', but argument 2 has type 'double'


Bonne prog,
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
25 oct. 2010 à 21:10
Salut Chouchou,

Shame on me! Je n'ai plus les yeux en face des trous et en plus en me relisant je viens de voir que mon explication ne correspond pas à l'idée que je souhaitais faire passer.
Promis je prendrais le temps de relire au prochain coup ;)

Shell
0
Rejoignez-nous