2010-09-15 4 views
2

Je travaille sur un projet c existant (spglib sur sourceforge), et je suis en cours d'exécution dans le problème après le nettoyage des initialisations de tableau:*** glibc détecté *** gratuit(): invalide taille suivante (rapide) - devrait fonctionner?

* glibc détectée * tests/spglibtest: free() : taille suivante invalide (rapide): 0x08ab46e0 ***

le est backtrace:

#0 0xb7fe1424 in __kernel_vsyscall() 
#1 0xb5cfdd61 in raise() from /lib/libc.so.6 
#2 0xb5cff5ee in abort() from /lib/libc.so.6 
#3 0xb5d397ed in ??() from /lib/libc.so.6 
#4 0xb5d3f7b1 in ??() from /lib/libc.so.6 
#5 0xb5d4052b in ??() from /lib/libc.so.6 
#6 0xb5d441cd in free() from /lib/libc.so.6 
#7 0xb6681484 in sym_get_multiplicity (cell=0xbfffe1f0, symprec=0.050000000000000003) at /git/xtalopt-public/src/spglib/symmetry.c:168 
#8 0xb6680550 in spg_find_primitive (lattice=0xbfffe2a8, position=0x813c6f0, types=0x813c700, num_atom=2, symprec=0.050000000000000003) 
    at /git/xtalopt-public/src/spglib/spglib.c:253 

l'erreur est dans la ligne "libre (trans)" ci-dessous:

int sym_get_multiplicity(const Cell *cell, const double symprec) 
{ 
    int i, rc; 
    double **trans; 
    trans = (double**)malloc(cell->size * sizeof(double*)); 
    for (i = 0; i < cell->size; i++) { 
    trans[i] = (double*)malloc(3 * sizeof(double)); 
    } 

    rc = get_translation(&trans[0][0], identity, cell, symprec); 

    for (i = 0; i < cell->size; i++) { 
    free(trans[i]); 
    } 
    free(trans); 

    return rc; 
} 

get_translation attribue des valeurs à trans comme ceci:

static int get_translation(double trans[][3], const int rot[3][3], const Cell *cell, 
          const double symprec) 
{ 
... 
    for (j = 0; j < 3; j++) { 
    trans[num_trans][j] = someDouble; 
    } 
... 
} 

Valgrind montre ce qui suit lors de l'écriture au tableau dans get_translation:

==17929== Invalid write of size 8 
==17929== at 0x56BE8A7: get_translation (symmetry.c:285) 
==17929== by 0x56BE44B: sym_get_multiplicity (symmetry.c:163) 
... 
==17929== Address 0x9cb5868 is 0 bytes after a block of size 8 alloc'd 
==17929== at 0x4024918: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==17929== by 0x56BE3F7: sym_get_multiplicity (symmetry.c:158) 
.... 

Cela me donne à penser qu'il est en train d'écrire après la fin de la mémoire allouée pour trans, mais il écrit à trans [0] [0], et trans est de dimension [2] [3]. Cela devrait fonctionner, AFAIK, quelqu'un peut-il voir quelque chose qui me manque?

+0

Ainsi, alors que pas une réponse, trans n'est pas strictement le même que quelque chose défini comme deux trans [2] [3]. En particulier trans [0] [2] et trans [1] [0] ne sont pas placés séquentiellement en mémoire dans votre exemple, ce qui est nécessaire pour quelque chose comme dobule trans [2] [3]. –

+0

Vous devriez obtenir un « argument passé de type pointeur incompatible » avertissement sur l'appel à 'get_translation()' - Je suggère tourner votre niveau d'avertissement du compilateur. – caf

+0

Vraiment pas sûr pourquoi cela a été marqué comme un doublon. Le message d'erreur incroyablement générique est le même, mais le problème sous-jacent est assez différent ... – dlonie

Répondre

6

Vos types sont mauvais, vous ne pouvez pas passer un pointeur sur un tableau de pointeurs vers une fonction attendant un tableau de tableaux (par exemple un pointeur sur un tableau).

Pour la signature de get_translation que vous avez, vous avez besoin:

double (*trans)[3] = malloc(cell->size * sizeof(double[3])); 
+0

Du point de vue de la gestion de la mémoire, cela a du sens pour moi, et ça marche quand je fais le changement - Merci! Cependant, j'ai un peu de mal à comprendre la syntaxe de la déclaration, et googling n'a pas trouvé beaucoup d'informations à ce sujet. Pouvez-vous recommander une référence sur cette technique? Merci encore! – dlonie

+0

@dlonie: Quelques questions récentes sur ce sujet sont: http://stackoverflow.com/questions/3707096/ et http://stackoverflow.com/questions/3706704/. –

+0

Ah, je vois maintenant. J'ai été ébranlé en voyant un pointeur déréférencé dans sa déclaration - plutôt inintéressant basé sur mon expérience C++! Le conseil sur la règle en spirale a aidé à éclaircir cela. – dlonie

2

est ici peut-être un SO problème. Votre fonction semble supposer (basé sur) trans [num_trans] [j] = someDouble; ce trans est en fait un tableau agencé séquentiellement, ce qui, comme je l'ai mentionné plus haut, n'est pas vrai dans ce cas. Vous allouez un tableau de pointeurs plutôt qu'un tableau à deux dimensions. Quelque chose de semblable à

double * trans = malloc (Cell-> Taille * 3); pourrait être mieux. En général, vous pouvez utiliser un tableau 1d au lieu d'un tableau 2d et l'utiliser comme tableau à deux dimensions.

Questions connexes