2009-08-05 6 views
2

Je développe une application de traitement d'image en C++. J'ai vu beaucoup d'erreurs de compilation et de backtraces, mais celui-ci est nouveau pour moi.Strange backtrace - où est l'erreur?

#0 0xb80c5430 in __kernel_vsyscall() 
#1 0xb7d1b6d0 in raise() from /lib/tls/i686/cmov/libc.so.6 
#2 0xb7d1d098 in abort() from /lib/tls/i686/cmov/libc.so.6 
#3 0xb7d5924d in ??() from /lib/tls/i686/cmov/libc.so.6 
#4 0xb7d62276 in ??() from /lib/tls/i686/cmov/libc.so.6 
#5 0xb7d639c5 in malloc() from /lib/tls/i686/cmov/libc.so.6 
#6 0xb7f42f47 in operator new() from /usr/lib/libstdc++.so.6 
#7 0x0805bd20 in Image<Color>::fft (this=0xb467640) at ../image_processing/image.cpp:545 

Que se passe-t-il ici? L'opérateur new plante, ok. Mais pourquoi? Ce n'est pas un manque de mémoire (il essaie d'allouer environ 128 Ko, un 128x64 pixels avec deux flotteurs chacun). De plus, cela ne fonctionne pas car c'est une erreur dans mon propre code (le constructeur ne se fait pas toucher!).

Le code dans la ligne mentionnée (# 7) est:

Image<Complex> *result = new Image<Complex>(this->resX, resY); 
// this->resX = 128, resY = 64 (both int), Complex is a typedef for std::complex<float> 

Presque la même instanciation travaille sur d'autres endroits dans mon code. Si je commente cette partie du code, il va planter un peu plus tard sur une partie similaire. Je ne comprends pas, je n'ai pas non plus d'idées, comment le déboguer. De l'aide?

compilateur gcc 4.3.3, libc est 2.9 (tous deux de Ubuntu Jaunty)

Mise à jour:

J'ai inclus les lignes suivantes juste au-dessus de la ligne défectueuse dans la même méthode et en principal()

Image<Complex> *test = new Image<Complex>(128, 64); 
    delete test; 

la chose étrange: dans la même méthode, il se bloque, dans le principal() il ne sera pas. Comme je l'ai mentionné, Complex est un typedef de std :: complex <float>. Le constructeur n'est pas appelé, j'ai inséré un cout juste avant cette ligne et dans le constructeur lui-même.

Mise à jour 2:

Merci à KPexEA pour cette astuce! J'ai essayé ceci:

Image<Complex> *test = new Image<Complex>(128, 64); 
delete test; 

kiss_fft_cpx *output = (kiss_fft_cpx*) malloc(this->resX * this->resY/2 * sizeof(kiss_fft_cpx)); 
kiss_fftndr(cfg, input, output); 

Image<Complex> *test2 = new Image<Complex>(128, 64); 
delete test2; 

Il se bloque à - vous devinez? - test2! Donc le malloc pour mes coutures kissfft pour être le défectueux. Je vais y jeter un coup d'oeil.

mise à jour finale:

Ok, il est fait! Merci à tous!

En fait, j'aurais dû le remarquer avant. La semaine dernière, j'ai remarqué, que kissfft (une bibliothèque de transformée de Fourier rapide) a fait une image fft de 130x64 pixels à partir d'une image source de 128x128 pixels. Oui, 130 pixels de large, pas 128. Ne me demandez pas pourquoi, je ne sais pas! Donc, 130x64x2xsizeof (float) octets devaient être alloués, pas 128x64x ... comme je le pensais avant. Étrange, qu'il ne s'est pas écrasé juste après avoir corrigé ce bug, mais quelques jours plus tard.

Pour mémoire, mon code final est:

int resY = (int) ceil(this->resY/2); 

kiss_fft_cpx *output = (kiss_fft_cpx*) malloc((this->resX+2) * resY * sizeof(kiss_fft_cpx)); 
kiss_fftndr(cfg, input, output); 

Image<Complex> *result = new Image<Complex>(this->resX, resY); 

Merci!

craesh

+0

Peut-être ajouter un exemple de l'instanciation "presque la même" qui fonctionne? – Amber

Répondre

5

Peut-être une partie de mémoire allouée précédemment a un débordement de tampon qui corrompt le tas?

+1

Je vois vraiment ce type d'erreur aléatoire quand un accès hors limites est fait, vérifiez le reste de votre code, rappelez-vous que vous pouvez accéder en dehors des limites sans erreur immédiate, il se cache et apparaît aléatoirement dans malloc/gratuit nouveau/Supprimer les appels Un des bugs les plus frustrants à suivre que je trouve. – DeusAduro

0

Vous n'allouez pas assez de mémoire.Le format demi-spectre de kissfft (et FFTW et IMKL d'ailleurs) contient des éléments complexes X * (Y/2 + 1).

Voir le fichier d'en-tête de kiss_fftndr.h:

/* TimeData d'entrée a dim [0] X dim [1] X ... X dim [NDIMS-1] points scalaires

freqdata de sortie a dims [0] X dims [1] X ... X dims [ndims-1]/2 + 1 points complexes *