erreur de segmentation pourtant simple

erreur de segmentation pourtant simple - C - Programmation

Marsh Posté le 06-05-2005 à 00:14:04    

une petite procédure   d'intialisation de matrice :
(et ça bloque déja  :cry: )
 
typedef int **matrice;
 void intmatrice( matrice mat){
    int i,j;
    mat=malloc(sizeof(matrice));
  for (i=0;i<4;i++){
    for (j=0;j<4;j++){
       mat[i][j]=0;
 
    }
  }
  }
int main(){
 
matrice mat= malloc(sizeof(matrice));
intmatrice(mat);
}
 
et l'exécution m'affiche une erreur de segmentation!!!! :ouch:  !
les 2 malloc n'ont pas suffit ( je suis presque certaine qu'il faut meme pas mettre les 2)
alors vous pensez quoi ?
merci pour votre aide!

Reply

Marsh Posté le 06-05-2005 à 00:14:04   

Reply

Marsh Posté le 06-05-2005 à 00:16:21    

et oui, c'est déjà vendredi...


---------------
Nos estans firs di nosse pitite patreye...
Reply

Marsh Posté le 06-05-2005 à 00:21:58    

Code :
  1. #include <stddef.h>
  2. struct Matrice
  3. {
  4. int elements[4][4];
  5. };
  6. void initmatrice(struct Matrice* mat, int valeur)
  7. {
  8. size_t i, j;
  9. for(i = 0; i < 4; ++i)
  10.  for(j = 0; j < 4; ++j)
  11.   mat->elements[i][j] = valeur;
  12. }
  13. int main()
  14. {
  15. struct Matrice m;
  16. initmatrice(&m, 42);
  17. return 0;
  18. }

Reply

Marsh Posté le 06-05-2005 à 00:57:14    

sam15 a écrit :

une petite procédure   d'intialisation de matrice :
(et ça bloque déja  :cry: )


Déjà, ça, ça n'aide pas :

main.c: In function `intmatrice':
main.c:15: warning: implicit declaration of function `malloc'
main.c:15: warning: assignment makes pointer from integer without a cast
main.c: At top level:
main.c:23: warning: function declaration isn't a prototype
main.c: In function `main':
main.c:25: warning: initialization makes pointer from integer without a cast
main.c:27: warning: control reaches end of non-void function


ensuite, ce code est sérieusement buggé...
 
Une matrice dynamique carrée de N x N de type T est composée :

  • d'un pointeur pouvant recevoir l'adresse d'un tableau de N pointeurs de type T.
  • de N tableaux de N objets de type T

les adresses de ces N tableaux sont enregistées dans le tableau de pointeur.
 
Voilà comment on fait :  
 

/* allocation du tableau de N pointeurs */
int **mat = malloc (sizeof *mat * N);
 
/* pour chaque pointeur, définir un tableau de N int */
int i;
 
for (i = 0; i < N; i++)
{
   mat[i] = malloc (sizeof *mat[i] * N);
}


 
http://mapage.noos.fr/emdel/notes.htm#malloc
 
Dans la réalité, on ajoute les headers qui vont bien et des sécurités. En effet, malloc() peut échouer.
Pour l'init, voir les boucles imbriquées dans le code de Taz.
 
Il faut cesser de programmer au hasard et commencer à secouer son neurone.
 
Si la matrice est de taille fixe, le code de Taz est correct et suffisant.


Message édité par Emmanuel Delahaye le 06-05-2005 à 01:03:03

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 01:03:22    

Merci bcp "Emmanuel D elahaye",
j'ai raisonné comme si j'avais un tableau à une dimension.  
alors que c'est pas du tout pareil  :non:  
j'ai plus l'erreur de segmentation  :bounce:  
 merci bcp pour ton aide.

Reply

Marsh Posté le 06-05-2005 à 08:15:36    

mais une matrice c'est un truc qui a des lignes et des colonnes, et en memoire c'est pareil, pas un sac a burnes

Reply

Marsh Posté le 06-05-2005 à 15:13:21    

et non en mémoire tu n'as pas deux dimensions, mais qu'une. Au niveau logique tu as donc des lignes et des colonnes. Mais en mémoire tout est contigue, donc toute les lignes sont l'une a coté de l'autre
 

Reply

Marsh Posté le 06-05-2005 à 15:19:45    

moi23372 a écrit :

et non en mémoire tu n'as pas deux dimensions, mais qu'une. Au niveau logique tu as donc des lignes et des colonnes. Mais en mémoire tout est contigue, donc toute les lignes sont l'une a coté de l'autre


Si on définit un tableau statique à deux dimensions, oui. Idem si on alloue un tableau de NxM, mais dans ce cas, il fait calculer les indices à la main.  
 
Dans le cas que j'ai montré, (allocation dynamique avec accès par syntaxe [i][j]), il s'agit d'un tableau de pointeurs sur des tableaux, et dans ce cas, la mémoire n'est pas contigue.


Message édité par Emmanuel Delahaye le 06-05-2005 à 15:20:45

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 15:24:18    

oui mais la on parle d'adresse, les adresses sont effectivement stockée de façon contigue en mémoire, c'est uniquement les valeurs même qui sont stockées un peu partout

Reply

Marsh Posté le 06-05-2005 à 15:37:29    

moi23372 a écrit :

oui mais la on parle d'adresse, les adresses sont effectivement stockée de façon contigue en mémoire, c'est uniquement les valeurs même qui sont stockées un peu partout


Chaque tableau est, par définition, fait de mémoire contigue, mais dans le cas d'un matrice NxM dynamique comme je l'ai montrée, il y a N + 1 tableaux, et ils sont indépendants.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 15:37:29   

Reply

Marsh Posté le 06-05-2005 à 15:52:58    

sauf si tu fais ton allocation comme un sioux :D

Reply

Marsh Posté le 06-05-2005 à 15:54:25    

moi23372 a écrit :

et non en mémoire tu n'as pas deux dimensions, mais qu'une. Au niveau logique tu as donc des lignes et des colonnes. Mais en mémoire tout est contigue, donc toute les lignes sont l'une a coté de l'autre


 
tu n'as pas compris ce que j'ai dis, une matrice c'est des lignes et des colonnes et en memoire c'est pareil, ca ve juste dire que c'est une vue sur un stream :o
 
edit: c'est comme ca que doit etre une matrice, surtout au niveau performance


Message édité par skelter le 06-05-2005 à 15:55:37
Reply

Marsh Posté le 06-05-2005 à 16:46:02    

Taz a écrit :

sauf si tu fais ton allocation comme un sioux :D

Oui en mettant l'adresse des 'sous-blocs' dans le tableau de pointeur (une sorte d'indexation). Effectivement, j'avais oublié cette ruse... qui est pas mal en fait. 2 allocations, , memoire contigue, syntaxe tableau...


Message édité par Emmanuel Delahaye le 06-05-2005 à 16:47:07

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 16:48:26    

Tu peux nous montrer un petit exemple ?

Reply

Marsh Posté le 06-05-2005 à 16:55:25    

push a écrit :

Tu peux nous montrer un petit exemple ?



/* allocation du tableau de N x N pointeurs */
int *mat = malloc (sizeof *mat * N * N);
 
/* allocation du tableau de N pointeurs */
int **pmat = malloc (sizeof *pmat * N);
 
/* pour chaque pointeur, enregistrer sa position dans le tableau N x N */
int i;
 
for (i = 0; i < N; i++)
{
   pmat[i] = mat + (i * N); /* je le sens mal, j'ai du me f**tre dedans avec les calculs... */
}  


Message édité par Emmanuel Delahaye le 06-05-2005 à 17:04:50

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 17:00:05    

Emmanuel Delahaye a écrit :

Oui en mettant l'adresse des 'sous-blocs' dans le tableau de pointeur (une sorte d'indexation). Effectivement, j'avais oublié cette ruse... qui est pas mal en fait. 2 allocations, , memoire contigue, syntaxe tableau...


1 seule !

Reply

Marsh Posté le 06-05-2005 à 17:02:59    


Dynamique et avec l'accès en [i][j] ? Alors là, je veux bien un exemple.


Message édité par Emmanuel Delahaye le 06-05-2005 à 17:03:56

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 17:06:47    

mais si, au lieu de faire 2 malloc, tu n'en fait qu'un seul et après tu fais un peu plus de gymnastique et voilà :)

Reply

Marsh Posté le 06-05-2005 à 17:09:52    

int *mat = malloc (sizeof *mat * N * N);
 
et apres
 
mat[ i*N + j ], je vois que ca (peut avec une macro) ? et la au moins c'est cache-friendly

Reply

Marsh Posté le 06-05-2005 à 17:10:17    

Taz a écrit :

mais si, au lieu de faire 2 malloc, tu n'en fait qu'un seul et après tu fais un peu plus de gymnastique et voilà :)


Tu veux dire écrire des fonction/macros qui calculent l'index en fonction de i, j et la largeur, c'est ça ? On ne peut donc pas utiliser directement [i][j], ok ?


Message édité par Emmanuel Delahaye le 06-05-2005 à 17:11:58

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 17:12:34    

mais non, exactement comme ton code, sauf qu'au lieu de 2 malloc, tu en fais 1 seul, que tu divises à la main.

Reply

Marsh Posté le 06-05-2005 à 17:17:55    

Un truc comme ça ?
 

int **pmat = (int**)malloc ((sizeof *pmat * N) + (sizeof **pmat * N * N));  
 
{
  int *mat = (int*)pmat + (sizeof *pmat * N);  
  int i;  
  for (i = 0; i < N; i++)  
  {  
    pmat[i] = mat;
    mat += N;
  }
}

Reply

Marsh Posté le 06-05-2005 à 17:19:34    

Taz a écrit :

mais non, exactement comme ton code, sauf qu'au lieu de 2 malloc, tu en fais 1 seul, que tu divises à la main.


Et les adresses, tu les rangent où ? Il faut bien allouer un tableau d'index, non ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 17:20:44    

ben oui, tu l'alloue avant ou apres en continuité

Reply

Marsh Posté le 06-05-2005 à 17:20:58    

ben comme Tarabiscote

Reply

Marsh Posté le 06-05-2005 à 17:22:56    

pourquoi ne pas faire tout simplement
int *mat = malloc (sizeof *mat * N * N);
et indexer avec une macro ?

Reply

Marsh Posté le 06-05-2005 à 17:23:22    

Taz a écrit :

ben comme Tarabiscote


Ok, vachement rusé...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 17:24:07    

:P j'ai pas dit que c'était intelligent, mais pourquoi pas :D

Reply

Marsh Posté le 06-05-2005 à 17:27:52    

Taz a écrit :

:P j'ai pas dit que c'était intelligent, mais pourquoi pas :D


Si, si, je trouve ça assez malin comme solution...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-05-2005 à 23:31:53    

skelter a écrit :

pourquoi ne pas faire tout simplement
int *mat = malloc (sizeof *mat * N * N);
et indexer avec une macro ?


 
+1, à l'ancienne.


Message édité par ++fab le 06-05-2005 à 23:33:13
Reply

Marsh Posté le 06-05-2005 à 23:33:04    

c'est moche, lourd à utiliser et potentiellement source d'erreur.

Reply

Marsh Posté le 06-05-2005 à 23:35:46    

lourd peut etre, mais pas moche.

Reply

Marsh Posté le 06-05-2005 à 23:37:28    

mais c'est astucieux quand meme, je n'y avais jamais pensé.

Reply

Marsh Posté le 06-05-2005 à 23:37:41    

++fab> pourquoi tu nommes ça "à l'ancienne" ?

Reply

Marsh Posté le 06-05-2005 à 23:42:45    

++fab a écrit :

lourd peut etre, mais pas moche.


alors fais le pour tous les tableaux, n'utilise que les void*, dis non au typage.

Reply

Marsh Posté le 06-05-2005 à 23:43:05    

bof, parce que mes anciens profs, eux memes anciens, ne faisait toujours qu'un seul malloc quelquesoit le nombre de dimensions du tableau, ... Des maniacs de la contiguité, mais ça a du bon.

Reply

Marsh Posté le 06-05-2005 à 23:44:41    

Taz a écrit :

alors fais le pour tous les tableaux, n'utilise que les void*, dis non au typage.


 
je disais lourd certes pour l'indexation à la mimine.

Reply

Marsh Posté le 06-05-2005 à 23:49:11    

vive le C peluche peluche

Reply

Marsh Posté le 06-05-2005 à 23:53:53    

et qu'est-ce qu'on se fait chier à faire du calcul matriciel en C, d'abord ? :o

Reply

Marsh Posté le 07-05-2005 à 00:01:58    

en admettant qu'on ai pas le choix autant le faire correctement, int** (matrice fragmentée) est la pire des solution

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed