Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1959 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Manipulation de matrices, Allocation dynamique...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Manipulation de matrices, Allocation dynamique...

n°1515113
bad___day
Posté le 15-02-2007 à 16:16:54  profilanswer
 

Salut,
J'ai un problème (à l'exécution) avec un petit code qui manipule des matrices allouer dynamiquement, et je ne comprend pas d'où est ce que l'erreur peut elle venir !
voici le code source (incomplet pour l'instant):

Code :
  1. void Allocate_Memory(int **A, int N, int M)
  2. {
  3.     int i;
  4.     A = (int**) malloc(sizeof(int*) * N);
  5.     for(i=0; i<N; i++)
  6.         A[i] = (int*) malloc(sizeof(int) * M);
  7. }


 
Merci pour votre aide.

Message cité 2 fois
Message édité par bad___day le 24-02-2007 à 13:08:42
mood
Publicité
Posté le 15-02-2007 à 16:16:54  profilanswer
 

n°1515192
Emmanuel D​elahaye
C is a sharp tool
Posté le 15-02-2007 à 17:55:30  profilanswer
 

bad___day a écrit :

voici le code source (incomplet pour l'instant):


Déjà ça, ça craint...


Project   : Forums
Compiler  : GNU GCC Compiler (called directly)
Directory : C:\dev\forums2\
--------------------------------------------------------------------------------
Switching to target: default
Compiling: main.c
main.c: In function `Sous_Menu':
main.c:183: warning: control reaches end of non-void function
main.c: In function `main':
main.c:22: warning: 'matrice1' might be used uninitialized in this function
main.c:22: warning: 'matrice2' might be used uninitialized in this function
Linking console executable: console.exe
Process terminated with status 0 (0 minutes, 5 seconds)
0 errors, 3 warnings


---------------
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/
n°1515197
bad___day
Posté le 15-02-2007 à 18:09:47  profilanswer
 

Pour le warning main.c:183: warning: control reaches end of non-void function
Ce n'ai pas bien grave car je n'ai pas besoin de retourné quoi que ce soit a la fin de la fonction,
puisque je retourne obligatoirement quelque chose dans mes switch() et que j'ai fait un controle de saisi.
 
Pour les deux autre warning, je ne saisi pas  :sweat:  , car je n'ai pas besoin de les initialisé, je passe les adresse a la fonction qui fait l'allocation !
 
NB: Ne pas regarder l'utilisation de scanf() , car c'est juste pour les essayes..
 
 

n°1515203
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 15-02-2007 à 18:14:48  profilanswer
 

Citation :


    A = (int**) malloc(sizeof(int*) * N);
    for(i=0; i<N; i++)
        A[i] = (int*) malloc(sizeof(int) * M);


 
On ne caste pas un malloc :o

n°1515205
bad___day
Posté le 15-02-2007 à 18:15:27  profilanswer
 

dave_tetehi a écrit :

On ne caste pas un malloc :o


Ok :) , mais ça ne change pas grand chose au prob. lol

 


Message édité par bad___day le 15-02-2007 à 18:16:30
n°1515207
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 15-02-2007 à 18:20:58  profilanswer
 

Citation :


            case 11:
            {
                int N, M;
                printf("Donnez la dimmantion des matrices:\n" );
                printf("Nombre de ligne:  " );
                scanf("%d", &N);
                printf("Nombre de colonne:  " );
                scanf("%d", &M);
                Allocate_Mat_Memory(matrice1, N, M);
                Allocate_Mat_Memory(matrice2, N, M);
                Saisi_Mat(matrice1, N, M);
                Saisi_Mat(matrice2, N, M);
                //Add_Soust_Mat( '+', matrice1, matrice2, N, M);
                //Affiche_Mat(matrice1, N, M);
                //Free_Mat_Memory(matrice1, N);
                //Free_Mat_Memory(matrice2, N);
            }
            break;
 
            case 12:
                //Add_Soust_Mat( '-', matrice1, matrice2, N, M);


 
Il ne faut pas initialiser N, M dans le bloc case 11, si vous compter les utiliser dans le bloc case 12.

n°1515209
bad___day
Posté le 15-02-2007 à 18:24:56  profilanswer
 

dave_tetehi a écrit :

Il ne faut pas initialiser N, M dans le bloc case 11, si vous compter les utiliser dans le bloc case 12.


je vais les réinitialiser dans ce cas... a chaque bloc, car ce n'ai pas les même dimensions que l'utilisateur dois utilisé a chaque case...

 


De toute façons, le probléme qui apparés a l'execution n'ai pas à cause de ça ... !

 



Message édité par bad___day le 15-02-2007 à 18:28:04
n°1515210
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 15-02-2007 à 18:28:30  profilanswer
 

De plus votre allocation est fausse.
 

Citation :


void Allocate_Mat_Memory(int **A, int N, int M)
{
    int i;
 
    A = (int**) malloc(sizeof(int*) * N);
    for(i=0; i<N; i++)
        A[i] = (int*) malloc(sizeof(int) * M);
 
}


 
Vous êtes en train allouer de la mémoire pour une variable automatique qui va être détruite à la fin de la portée.
 
Pour faire ce que vous voulez faire, il faut passer en parmètre l'adresse du pointeur de pointeur.
 
 
Allocate_Mat_Memory( &matrice1, N, M);
 
avec un prototype comme ceci :
 
void Allocate_Mat_Memory(int ***A, int N, int M)

n°1515214
Emmanuel D​elahaye
C is a sharp tool
Posté le 15-02-2007 à 18:34:14  profilanswer
 

Le compilateur avait raison, il y a bien un bug...


main.c:22: warning: 'matrice1' might be used uninitialized in this function
main.c:22: warning: 'matrice2' might be used uninitialized in this function


Il faut toujours écouter son compilateur...
 

bad___day a écrit :


Code :
  1. int main(void)
  2. {
  3.     int **matrice1, **matrice2;
  4.        <...>
  5.                 Allocate_Mat_Memory(matrice1, N, M);
  6.                 Allocate_Mat_Memory(matrice2, N, M);




Problème récurrent. Si on veut qu'une fonction modifie la valeur d'une variable, il faut passer l'adresse de la variable via un paramètre pointeur du bon type ou retourner la valeur (beaucoup plus clair, parce que les ***, non merci...)...
 
http://mapage.noos.fr/emdel/notes. [...] e_variable
 
 
 


---------------
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/
n°1515227
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 15-02-2007 à 18:52:49  profilanswer
 

Citation :


A = (int**) malloc(sizeof(int*) * N);  
    for(i=0; i<N; i++)  
        A[i] = (int*) malloc(sizeof(int) * M);


 
D'ailleurs, ce n'est pas toujours la meilleur façon d'allouer la mémoire, rien ne vous garantit que votre mémoire sera allouée de façon contigu.
Après, tout dépend de ce que vous voulez en faire, mais bien souvent, un tableau (ex, une image) = balayage ligne par ligne, donc si c'est votre cas, cette méthode d'allocation est à bannir, je préconise plutot quelque chose de ce genre. Après, si votre mémoire est limitée, ou si votre matrice est vraiment très volumineuse, il faut mieux la segmenter, donc restez sur votre position.  :whistle:  

Code :
  1. int ** A = malloc(sizeof(int *) * N);
  2. int  * B = malloc(sizeof(int) * N*M);
  3. for(i=0; i < N; i++)
  4. {
  5. A[i] = B;
  6. B += M;
  7. }


mood
Publicité
Posté le 15-02-2007 à 18:52:49  profilanswer
 

n°1515232
lkolrn
&lt;comment ça marche?&gt;
Posté le 15-02-2007 à 19:07:07  profilanswer
 

Salut,
 
en général la fonction d'init d'un pointeur (sur variable simple, tableau, matriceXd, objet) retourne l'adresse d'un bloc mémoire qu'elle vient d'allouer,
alors que toi tu fais :

Code :
  1. void Allocate_Mat_Memory(int **A, int N, int M)

càd que tu renvoie que dalle...
 
Ya également la possibilité, comme le précise Emmanuel Delahaye, et comme tu l'as fait mais mal, de passer directement l'adresse de ton pointeur à la fonction d'init, c'est pratique dans certains cas, mais bon là typiquement il faut créer ton pointeur dans la fonction d'init, l'allouer, et le renvoyer à ton pointeur du même type, simplement déclaré au préalable et donc vide, dans ton main.
C'est généralement la bonne solution, et pour toi c'est important de le faire comme ça au début, ça va t'éclaircir les idées au lieu de t'embrouiller.
 
Pour t'aider à bien réaliser le truc, tu peux penser à l'init d'un pointeur comme on le fait en C++ :

Code :
  1. int * a;
  2. a = new(int);

Sauf que la tu "recodes" le new() à la main (et en C), mais le principe est le même : d'abord tu déclares un pointeur vide, et après tu lui appliques une fonction d'allocation mémoire, qui retourne le pointeur sur le bloc mémoire alloué.
 
Et aussi : printf() est ton amie :hello: T'en place quelques-uns à des endroits judicieux de ton code, comme ça tu sais où ça coince...
 
 
Edit
A propos de la remarque de dave_tetehi : faut po l'écouter :whistle: C'est déjà de l'optimisation alors que visiblement tu n'en es qu'à la phase d'apprentissage, et c'est trétrémal de mixer les 2 ensemble à ce stade...
Si tu regardes il additionne même un nombre entier à un pointeur quand il écrit B += M; ce qui fait avancer le pointeur dans ton tableau de M cases mémoire car tab[a] <=> *(tab+a) => (tab+a) est l'adresse de tab[a]. Bref, c'est pas nécessaire point de vue pédagogique, sauf si on l'explique hein :p
Enfin la manière dont sont ordonnés les blocs mémoire peut être importante voire primordiale, mais ici osef, d'autant plus que quand on veut vraiment optimiser un calcul matriciel pas trop énorme on utilise un vecteur et on joue directement avec les indices pour "simuler" une matrice :ange:


Message édité par lkolrn le 16-02-2007 à 05:15:50
n°1515904
davidenko
Posté le 17-02-2007 à 10:19:18  profilanswer
 

il faut utiliser une boucle for

n°1515906
-ThX-
Not here anymore
Posté le 17-02-2007 à 10:26:45  profilanswer
 

k lol.

n°1515986
bad___day
Posté le 17-02-2007 à 15:24:44  profilanswer
 

Je préfère récupérer la valeur retournée par ma fonction ( sans avoire à utilisé les *** ,  comme dit Emmanuel: retourner la valeur c'est beaucoup plus clair, parce que les ***, non merci... )
Mais dans ce cas comment je fait pour ma fonction Free_Mat_Memory() ?
Est ce que je suis obligé d'utiliser ***
 

n°1516042
lkolrn
&lt;comment ça marche?&gt;
Posté le 17-02-2007 à 21:54:55  profilanswer
 

A la limite on s'en fout de "préférer" ou pas, c'est comme ça que ça marche généralement, à ce stade (le tien) au moins :
quand on alloue de la mémoire, on retourne une adresse et on l'affecte à un pointeur vide du type correspondant.
 
Tu verras dans peu de temps comment faire avec l'adresse (d'un pointeur ici) passée en paramètre à la fonction d'allocation, mais pour l'instant il ne faut même pas le prendre en compte, tu sais que c'est une autre solution possible, point. Commencer par le commencement quoi...
 
Sinon, pour répondre à ta question sur la libération de la mémoire : tu passes directement ton pointeur à ta fonction, pas besoin d'ajouter un niveau d'indirection supplémentaire (càd l'adresse de ce pointeur). Par contre, il faut être vigileant à bien désallouer tout ce qui a été précédemment alloué, càd traiter chaque pointeur sur bloc mémoire, dans le sens contraire de l'allocation.
En gros, la fonction Free_Mat() est la correspondance contraire de Allocate_Mat(), chaque pointeur initialisé (par malloc ici) dans Allocate_Mat() selon un certain ordre doit être libéré dans Free_Mat(), selon l'ordre contraire.
C'est très logique, pour construire une pile d'assiettes on pose la première, puis la deuxième par dessus, etc... Et pour la détruire proprement on retire la dernière, celle en haut de la pile, puis l'avant-dernière, etc...
 
Donc là, de la même façon, pour créer ta matrice tu as d'abord créé un vecteur/tableau, sa "1ère ligne", et dans chaque case de ton vecteur tu as mis un pointeur sur un autre tableau, équivalent à chaque "colonne" de la matrice.
Dans l'autre sens maintenant, pour supprimer ta matrice, tu commences par free() chaque "colonne" de ta matrice, et pour finir tu libères la "1ère ligne".
 
 
 
PS : énorme le davidenko... [:skyx@v]  
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Manipulation de matrices, Allocation dynamique...

 

Sujets relatifs
Menu Dynamique en C++Manipulation de fichier
pb avec formulaire dynamique en HTML/JavaRequete web dynamique (VBA)
matrice statique et dynamiqueChargement dynamique de news
[MySQL v5] [Procédure Stockée] construire une requête dynamique ?Opérations matrices problème structure pointeur
Création dynamique de classe en PHP5 ?Tableau dynamique sous ASP.net (C# et SQL Server)
Plus de sujets relatifs à : Manipulation de matrices, Allocation dynamique...


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)