Allocation dynamique d'une matricec [Résolu]

Messages postés
3
Date d'inscription
dimanche 6 mars 2005
Statut
Membre
Dernière intervention
23 octobre 2010
- - Dernière réponse : DeAtHCrAsH
Messages postés
2674
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;
}
Afficher la suite 

6 réponses

Meilleure réponse
Messages postés
252
Date d'inscription
vendredi 13 juin 2003
Statut
Membre
Dernière intervention
25 avril 2011
3
Merci
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,

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 193 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_Chouchou182
Messages postés
3
Date d'inscription
dimanche 6 mars 2005
Statut
Membre
Dernière intervention
23 octobre 2010
0
Merci
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.
Commenter la réponse de djou45
Messages postés
3
Date d'inscription
dimanche 6 mars 2005
Statut
Membre
Dernière intervention
23 octobre 2010
0
Merci
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
Commenter la réponse de djou45
Messages postés
2674
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
0
Merci
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
Commenter la réponse de DeAtHCrAsH
Messages postés
252
Date d'inscription
vendredi 13 juin 2003
Statut
Membre
Dernière intervention
25 avril 2011
0
Merci
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,
Commenter la réponse de cs_Chouchou182
Messages postés
2674
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
0
Merci
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
Commenter la réponse de DeAtHCrAsH