Problème avec allocation dynamique de tableau (C) - C - Programmation
Marsh Posté le 07-04-2009 à 01:07:27
Remarque préliminaire : il manque #include <malloc.h> mais peut-être que cet include est fait automatiquement.
tab[0][0]=1; ne convient pas, car c'est équivalent à "la cellule mémoire qui se trouve à l'adresse de tab + 0 fois le nombre de colonnes + 0 = 1." Il y a deux problèmes : a) le nombre de colonnes n'étant pas spécifié, je ne sais pas ce que le compilateur va prendre, peut-être zéro ; b) l'adressage concerne le pointeur au lieu du pointeur de pointeur.
Le plus simple est d'utiliser un tableau à une seule dimension, avec un simple malloc(n*p*sizeof(int)) ou bien d'utiliser des pointeurs sur des pointeurs plutôt que la notation [][] qui adresse en fait un espace à une seule dimension.
Marsh Posté le 07-04-2009 à 08:39:40
Oui mais non. Pour la Neme fois, voila la façon correct d'allouer un tableau 2D contigue et supportant [][] et qui respecte le cache.
Code :
|
A dupliquer/generaliser pour les autres types.
Un tableau 2D dont les lignes sont des zones mémoires disjointes est la pire des choses à faire.
Marsh Posté le 07-04-2009 à 09:18:30
MKflo84 a écrit : Maintes excuses, j'ai cherché des réponses à ce sujet sur le forum et j'ai trouvé un élément de réponse, seulement je ne comprends pas pourquoi mon code ne fonctionne pas. Je souhaite créer à terme des tableaux de taille variable à l'exécution d'où mon intention d'utiliser l'allocation dynamique. J'ai commencé par le code suivant : |
Tu peux déjà corriger ça :
-------------- Build: Debug in hello --------------- Compiling: main.c |
Ensuite, il y a un ';' après un for, ce qui fait que ce qui est après n'est effectué qu'une seule fois...
Code :
|
est équivalent à
Code :
|
Ce qui n'est évidemment pas ce que tu attends...
Le cast est inutile. Ne pas oublier de libérer ce qui a été alloué.
Ceci fonctionne :
Code :
|
Process returned 0 (0x0) execution time : 0.574 s |
Il manque des contrôles pour vérifier si l'allocation a réussi.
Ceci peut aider :
http://mapage.noos.fr/emdel/notes.htm#tabdyn_2d
Marsh Posté le 07-04-2009 à 09:43:57
Joel F a écrit : Oui mais non. Pour la Neme fois, voila la façon correct d'allouer un tableau 2D contigue et supportant [][] et qui respecte le cache.
|
Ca ne change pas grand chose, à part une allocation un peu plus longue...
Ton code, une fois rendu compilable et testable, a l'air de fonctionner.
Code :
|
|
Marsh Posté le 07-04-2009 à 10:29:42
Emmanuel Delahaye a écrit : |
Bah, en terme de localité du cache et donc de perfs au final, ca change beaucoup
Emmanuel Delahaye a écrit : |
Ouais, j'ai recopié ça d'un source C++ un peut trop rapidement
Marsh Posté le 07-04-2009 à 11:52:38
Joel F a écrit : |
Tu veux dire qu'on fait un tir groupé... OK.
Marsh Posté le 07-04-2009 à 13:17:38
Merci à tous pour vos réponses.
J'ai fini par trouver hier soir tard, que tout venait de ce fameux ";" après for, qui rendait inopérante ma boucle et qui n'affectait que la dernière collonne de ma matrice. Je suis désolé d'avoir spamé le forum avec une boulette aussi grosse... mais celà a l'avantage de nous ammener à quelque chose de plus intéressant pour le profane que je suis :
La remarque de Joel F m'interpelle. Je comprend que la solution qu'il propose a l'avantage d'affecter des espaces contigus de mémoire pour les données (une seul malloc de taille k*n, vers lequel vont pointer les éléments du premier malloc) au lieu d'affecter autant d'espaces, potentiellement disjoints, qu'il y a de lignes pour ma "solution". Pourrais-t-on juste m'expliquer "simplement" (sans vouloir offenser personne) et un peu plus en détail ce que celà change en terme de perfs, pourquoi et si oui, me donner un ordre d'idée du rapport ? (1 ordre de grandeur ou plus ?)
Pour répondre à billgatesanonym, comme tab a été affecté d'après un malloc, la taille de la première dimension est connue (vu dans "la ref. du langage C" par C. Delanoy, p337 "retrouver artificiellement le formalisme du tableau" ).
Merci d'avance,
Marsh Posté le 07-04-2009 à 13:21:56
Joel F a écrit : |
En C++, on utilise new et delete...
Marsh Posté le 07-04-2009 à 13:31:32
Emmanuel Delahaye a écrit : |
Pas pour des types POD.
En outre, ce n'es pas malloc/free qui est à proscirire, c'est :
- le melange malloc/Delete, new/free
- malloc/free sur des types objets.
Marsh Posté le 07-04-2009 à 13:33:53
MKflo84 a écrit : |
Quand tu faix N malloc, les adresses sont potentiellement sur des pages mémoire ou du moins des zone smémoire discontinues.
Lorsque tu acces à tab[i][j], le processeur va tenter de charger tab[i][j] et ses k voisins contigus ou k est la taille d'une ligne du cache.
Avec des lignes discontinues, tu va forcement avoir des cache misses en fin de lignes car il ne pas remplir à fond sa ligne de cache.
Et en general, les cache misses = plein de cycles dans la tete car accéder au cache est 10x plus rapide que de charger depuis la memoire principale.
Marsh Posté le 06-04-2009 à 22:34:15
Bonjour à tous,
Maintes excuses, j'ai cherché des réponses à ce sujet sur le forum et j'ai trouvé un élément de réponse, seulement je ne comprends pas pourquoi mon code ne fonctionne pas.
Je m'explique simplement :
Je souhaite créer à terme des tableaux de taille variable à l'exécution d'où mon intention d'utiliser l'allocation dynamique.
J'ai commencé par le code suivant :
J'obtiens à l'exécution un exception d'accès en écriture (sous VS 2008 express) dès la première ligne d'affectation tab[0][0]=1;.
J'ai trouvé un topic similaire où le code suivant fonctionne :
Je ne comprends pas pourquoi ce dernier fonctionne tandis que le mien plante lamentablement... un petit peu d'aide serait très appréciée !
Merci à tous,
Flo
Message édité par MKflo84 le 06-04-2009 à 22:39:41