erreur de segmentation pourtant simple - C - Programmation
Marsh Posté le 06-05-2005 à 00:16:21
et oui, c'est déjà vendredi...
Marsh Posté le 06-05-2005 à 00:21:58
Code :
|
Marsh Posté le 06-05-2005 à 00:57:14
sam15 a écrit : une petite procédure d'intialisation de matrice : |
Déjà, ça, ça n'aide pas :
main.c: In function `intmatrice': |
ensuite, ce code est sérieusement buggé...
Une matrice dynamique carrée de N x N de type T est composée :
les adresses de ces N tableaux sont enregistées dans le tableau de pointeur.
Voilà comment on fait :
/* allocation du tableau de N pointeurs */ |
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.
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
j'ai plus l'erreur de segmentation
merci bcp pour ton aide.
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
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
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.
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
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.
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
edit: c'est comme ca que doit etre une matrice, surtout au niveau performance
Marsh Posté le 06-05-2005 à 16:46:02
Taz a écrit : sauf si tu fais ton allocation comme un sioux |
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...
Marsh Posté le 06-05-2005 à 16:55:25
push a écrit : Tu peux nous montrer un petit exemple ? |
|
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 !
Marsh Posté le 06-05-2005 à 17:02:59
Taz a écrit : 1 seule ! |
Dynamique et avec l'accès en [i][j] ? Alors là, je veux bien un exemple.
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à
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
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 ?
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.
Marsh Posté le 06-05-2005 à 17:17:55
Un truc comme ça ?
int **pmat = (int**)malloc ((sizeof *pmat * N) + (sizeof **pmat * N * N)); |
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 ?
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 ?
Marsh Posté le 06-05-2005 à 17:23:22
Taz a écrit : ben comme Tarabiscote |
Ok, vachement rusé...
Marsh Posté le 06-05-2005 à 17:27:52
Taz a écrit : j'ai pas dit que c'était intelligent, mais pourquoi pas |
Si, si, je trouve ça assez malin comme solution...
Marsh Posté le 06-05-2005 à 23:31:53
skelter a écrit : pourquoi ne pas faire tout simplement |
+1, à l'ancienne.
Marsh Posté le 06-05-2005 à 23:33:04
c'est moche, lourd à utiliser et potentiellement source d'erreur.
Marsh Posté le 06-05-2005 à 23:37:28
mais c'est astucieux quand meme, je n'y avais jamais pensé.
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.
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.
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.
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 ?
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
Marsh Posté le 06-05-2005 à 00:14:04
une petite procédure d'intialisation de matrice :
(et ça bloque déja )
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!!!! !
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!