[Résolu] Fonction retournant un tableau allouer dynamiquement

Fonction retournant un tableau allouer dynamiquement [Résolu] - C - Programmation

Marsh Posté le 09-03-2009 à 18:52:00    

Bonjour à tous,
 
Alors voilà mon problème, après avoir cherché sur de nombreux cours/tutoriels de C disponibles sur la toile et après avoir feuilleté ce forum, j'ai pas trouvé de solution à mon problème.  
 
Je souhaite initialiser un tableau dans une fonction et ensuite l'utiliser dans mon main. Je dois aussi faire cela pour des matrices, mais je suppose que quand j'aurais résolu mon problème pour le tableau, résoudre pour une matrice pas plus difficile. Comment faire cela proprement? Je pensais à allouer le tableau dans le main, puis passer l'adresse du tableau en argumen...
 
Voilà mon code simplifié (sur demande je peux fournir mon code entier, mais je pense avoir laissé toutes les parties importantes):
 

Code :
  1. uint64_t* keyScheduling();
  2. int main( int argc, char ** const argv )
  3. {
  4.     uint64_t *roundkey;
  5.  
  6.     // Paramaters of Encryption
  7.     // ...  
  8.     // keyScheduling     
  9.     roundkey = keyScheduling();   
  10.     free(roundkey);
  11. }
  12. uint64_t* keyScheduling()
  13. {
  14.         uint64_t *roundkey = (uint64_t *)malloc(nRounds*sizeof(uint64_t));
  15.         // Initialisation of roundkey
  16.         // ...
  17.         return roundkey;
  18. }


 
Et j'ai une erreure de ce type là à la compilation:  :fou:  

Code :
  1. *** glibc detected *** ./EncryptDecrypt: double free or corruption (out): 0x09ea50d8 ***


 
Merci d'avance pour votre aide!

Message cité 1 fois
Message édité par samlesu le 09-03-2009 à 21:45:40
Reply

Marsh Posté le 09-03-2009 à 18:52:00   

Reply

Marsh Posté le 09-03-2009 à 19:05:21    

bah le message est explicite. Si tu compiles ton programmes quasi tel-quel, tu n'auras aucun problème.

Reply

Marsh Posté le 09-03-2009 à 19:41:35    

Ceci n'est pas un message d'erreur? Ca signifie que ça marche?
J'ai déjà googler cette erreure avec aucune réponse concluante...

Reply

Marsh Posté le 09-03-2009 à 20:00:37    

Le message à l'air explicite. Vérifies que tu n'appelles pas deux fois free() sur le même bloc (d'après ton code, tu n'as pas l'air d'avoir fait cette erreur). Donc tu as probablement un buffer overflow (erreur classique, mais extrêmement chiante à débugger).
 
À tout hasard, et si ce n'est pas trop long, poste le code qu'il y a après :

Code :
  1. // Initialisation of roundkey

Reply

Marsh Posté le 09-03-2009 à 20:51:29    

Après:

Code :
  1. 1. // Initialisation of roundkey


C'est du code en C basique de ce type là:

Code :
  1. for(RoundNbr=0;RoundNbr<nRounds+1;RoundNbr++)
  2. {
  3.                 // MAJ de la clef
  4.  roundkey[RoundNbr] = var;
  5.                 // Opérations sur var basique
  6.                 // ...
  7. }


 
J'ai bien revérifier et dans tout mon code j'ai des free() que dans mon main donc ça vient pas de là. SI je mets la ligne (dans le main) free(roundkey) en commentaire, l'erreure disparaît.
 
L'erreure ne viendrait-elle pas du fait que j'alloue mon tableau dans ma fonction, et ensuite je retourne que le pointeur sur le premier élément; donc quand je fais free(roundkey) dans mon main, il ne trouve pas la zone allouée?
 
Et voici l'erreure en entier:

Code :
  1. *** glibc detected *** ./EncryptDecrypt: double free or corruption (out): 0x095f20d8 ***
  2. ======= Backtrace: =========
  3. /lib/tls/i686/cmov/libc.so.6[0xb7f8c454]
  4. /lib/tls/i686/cmov/libc.so.6(cfree+0x96)[0xb7f8e4b6]
  5. ./EncryptDecrypt[0x804857b]
  6. /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7f33685]
  7. ./EncryptDecrypt[0x8048391]
  8. ======= Memory map: ========
  9. 08048000-08049000 r-xp 00000000 08:01 5824536    /home/samlesu/Documents/DTU/PFE_Present_Cryptanalysis/C/EncryptDecrypt
  10. 08049000-0804a000 r--p 00001000 08:01 5824536    /home/samlesu/Documents/DTU/PFE_Present_Cryptanalysis/C/EncryptDecrypt
  11. 0804a000-0804b000 rw-p 00002000 08:01 5824536    /home/samlesu/Documents/DTU/PFE_Present_Cryptanalysis/C/EncryptDecrypt
  12. 095ea000-0960b000 rw-p 095ea000 00:00 0          [heap]
  13. b7e00000-b7e21000 rw-p b7e00000 00:00 0
  14. b7e21000-b7f00000 ---p b7e21000 00:00 0
  15. b7f1c000-b7f1d000 rw-p b7f1c000 00:00 0
  16. b7f1d000-b8075000 r-xp 00000000 08:01 3728192    /lib/tls/i686/cmov/libc-2.8.90.so
  17. b8075000-b8077000 r--p 00158000 08:01 3728192    /lib/tls/i686/cmov/libc-2.8.90.so
  18. b8077000-b8078000 rw-p 0015a000 08:01 3728192    /lib/tls/i686/cmov/libc-2.8.90.so
  19. b8078000-b807b000 rw-p b8078000 00:00 0
  20. b807b000-b8088000 r-xp 00000000 08:01 3710997    /lib/libgcc_s.so.1
  21. b8088000-b8089000 r--p 0000c000 08:01 3710997    /lib/libgcc_s.so.1
  22. b8089000-b808a000 rw-p 0000d000 08:01 3710997    /lib/libgcc_s.so.1
  23. b808a000-b808d000 rw-p b808a000 00:00 0
  24. b808d000-b80a7000 r-xp 00000000 08:01 3710988    /lib/ld-2.8.90.so
  25. b80a7000-b80a8000 r-xp b80a7000 00:00 0          [vdso]
  26. b80a8000-b80a9000 r--p 0001a000 08:01 3710988    /lib/ld-2.8.90.so
  27. b80a9000-b80aa000 rw-p 0001b000 08:01 3710988    /lib/ld-2.8.90.so
  28. bf895000-bf8aa000 rw-p bffeb000 00:00 0          [stack]
  29. Aborted


 
Et merci pour vos réponses si rapide!

Message cité 1 fois
Message édité par samlesu le 09-03-2009 à 20:51:54
Reply

Marsh Posté le 09-03-2009 à 20:58:15    

Code :
  1. uint64_t *roundkey = (uint64_t *)malloc(nRounds*sizeof(uint64_t));
  2. for(RoundNbr=0;RoundNbr<nRounds+1;RoundNbr++) {
  3.    roundkey[RoundNbr] = var;


Soit tu alloues un trop peu, soit tu passes une fois de trop.

Reply

Marsh Posté le 09-03-2009 à 21:39:43    

et utilise 'i' comme variable de boucle, pas un affreux RoundNbr avec une casse pourrie

Reply

Marsh Posté le 09-03-2009 à 21:45:16    

Merci "Un Programmeur", tu avais parfaitement raison, j'allouais une case de moins. Problème réglé.
 
Concernant mon affreux indice, j'ai lu que pour plus de lisibilité dans les gros projets, il valait mieux utiliser des variables qui avaient une signification, pour être sur de ne pas confondre deux variables (j'ai donner que une petite partie de mon code).  
 
Merci beaucoup, problème résolu.

Message cité 1 fois
Message édité par samlesu le 09-03-2009 à 22:37:04
Reply

Marsh Posté le 09-03-2009 à 22:24:39    

samlesu a écrit :

Concernant mon affreux indice, j'ai lu que pour plus de lisibilités dans les gros projets, il valait mieux utiliser des variables qui avaient une signification, pour être sur de ne pas confondre deux variables (j'ai donner que une petite partie de mon code).

C'est faux. C'est illisible. i, j et k sont des noms des variables d'indices traditionnels.

Reply

Marsh Posté le 10-03-2009 à 08:09:25    

samlesu a écrit :

Je souhaite initialiser un tableau dans une fonction et ensuite l'utiliser dans mon main. Je dois aussi faire cela pour des matrices, mais je suppose que quand j'aurais résolu mon problème pour le tableau, résoudre pour une matrice pas plus difficile. Comment faire cela proprement? Je pensais à allouer le tableau dans le main, puis passer l'adresse du tableau en argumen...
 
Voilà mon code simplifié (sur demande je peux fournir mon code entier, mais je pense avoir laissé toutes les parties importantes):
 

Code :
  1. uint64_t* keyScheduling();
  2. int main( int argc, char ** const argv )
  3. {
  4.     uint64_t *roundkey;
  5.  
  6.     // Paramaters of Encryption
  7.     // ...  
  8.     // keyScheduling     
  9.     roundkey = keyScheduling();   
  10.     free(roundkey);
  11. }
  12. uint64_t* keyScheduling()
  13. {
  14.         uint64_t *roundkey = (uint64_t *)malloc(nRounds*sizeof(uint64_t));
  15.         // Initialisation of roundkey
  16.         // ...
  17.         return roundkey;
  18. }


Et j'ai une erreure de ce type là à la compilation:  :fou:  

Code :
  1. *** glibc detected *** ./EncryptDecrypt: double free or corruption (out): 0x09ea50d8 ***




nRounds n'est pas définie. C'est une globale ? Pourquoi ce n'est pas un paramètre de la fonction ?
 
Le code fourni ne peut pas provoquer l'erreur indiquée. Le problème est ailleurs.
 


---------------
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 10-03-2009 à 08:09:25   

Reply

Marsh Posté le 10-03-2009 à 08:15:24    

samlesu a écrit :

Après:

Code :
  1. 1. // Initialisation of roundkey


C'est du code en C basique de ce type là:

Code :
  1. for(RoundNbr=0;RoundNbr<nRounds+1;RoundNbr++)
  2. {
  3.                 // MAJ de la clef
  4.  roundkey[RoundNbr] = var;
  5.                 // Opérations sur var basique
  6.                 // ...
  7. }
 



Basique, mais faux (comportement indéfini). Tu fais un tour de trop. Pourquoi ce +1 ?

 

Je rappelle que les indices valides d'un tableau de N éléments vont de 0 à N-1.

 

La boucle 'canonique' qui génère ces indices est

 
Code :
  1. for (i = 0; i < N; i++)
  2. {
  3. }


Faut pas s'écarter des Bonnes Pratiques, sinon, on est quasiment sûr de se prendre une baffe...

 

Tu as beaucoup de chance que le défaut ait été capté aussi vite par ton système.

 

P.S. : Et Taz a raison. un indice, c'est i.


Message édité par Emmanuel Delahaye le 10-03-2009 à 08:16:46

---------------
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

Sujets relatifs:

Leave a Replay

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