Allocation dynamique d'une matricec [Résolu]

Signaler
Messages postés
3
Date d'inscription
dimanche 6 mars 2005
Statut
Membre
Dernière intervention
23 octobre 2010
-
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
-
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

Messages postés
252
Date d'inscription
vendredi 13 juin 2003
Statut
Membre
Dernière intervention
25 avril 2011

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,
Messages postés
3
Date d'inscription
dimanche 6 mars 2005
Statut
Membre
Dernière intervention
23 octobre 2010

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.
Messages postés
3
Date d'inscription
dimanche 6 mars 2005
Statut
Membre
Dernière intervention
23 octobre 2010

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
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
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
Messages postés
252
Date d'inscription
vendredi 13 juin 2003
Statut
Membre
Dernière intervention
25 avril 2011

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,
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
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