2010-10-25 2 views
0

C++. Cela peut être plus question de débogage dans Visual Studio et de travailler avec de la mémoire.BadPtr après plusieurs itérations

J'ai un programme qui analyse la liste des fichiers, et le chemin vers le fichier actuel est une concaténation de chaînes: Objet CString nommé «dossier» et nom de fichier lui-même (CString aussi).

Mais après 144 ième itération (je suis sûr que le nombre n'est pas important), le dossier se transforme soudainement en un BadPtr et l'application se bloque avec la violation d'accès. Pour vérifier, j'ai créé un objet CFileFind avec le même répertoire et au lieu de concaténer avec le dossier je concatène avec finder.GetRoot(). Même histoire, 144ème itération et crash. La question est, comment puis-je protéger la mémoire de cette variable (son ok avant la 144e itération) ou tracer la fonction qui écrit réellement sur cet emplacement ou quoi que ce soit d'autre pour déboguer ce problème. Pendant le cycle, la variable de dossier n'est pas modifiée du tout. En fait, c'est dans la section privée de certaines classes et toutes les fonctions apparaissant dans le cycle n'ont pas accès à cette section privée.

code va comme ça (il peut y avoir quelques fautes de frappe cuz i couper certaines choses sans importance sur elle):

typedef map<CString, list<CRect> > metadata; 
... 
metadata::iterator it=mt.begin(); 
list<CRect>::iterator it_l; 
float i=0; 

while(it!=mt.end()){ 
     if(cur.Load(folder+"\\"+(*it).first+".jpg")){ 
      it_l=(*it).second.begin(); 
      i+=1.0; 
      while(it_l!=(*it).second.end()){ 
       cur.buildVector(*it_l); 
       cur.printVector(mf,','); 
       mf<<",1"<<"\n"; 
       it_l++; 
      } 
     } 
     it++; 
    } 

buildVector recueille des caractéristiques dans l'objet CRect de l'image actuelle, cur.Load charge le CESTI d'image, printVector imprime le vecteur à ofstream nommé mf. Je compte les itérations.

MISE À JOUR: J'ai examiné mon code, j'ai commenté toutes les lignes mais cur.Load (...) et j'avais encore un crash mais sur 584th itération. On dirait que son problème de mémoire d'écrasement. Je regardais à travers toutes les fonctions en charge:

bool Image::Load(CString& path){ 
    if(!src.IsNull()){ 
     src.Destroy(); 
    } 
    src.Load(path);  
    width=src.GetWidth(); 
    height=src.GetHeight(); 
    fillBrightnessMatrix(); 
    fillGradientMatrices(); 
    return true; 
    } 

et a découvert que des commentaires fillBrightnessMatrix() fait des itérations passent par la fin de la liste sans aucune erreur. Cette fonction est la seule qui fonctionne avec la mémoire, et ici va son code:

void Image::fillBrightnessMatrix(){ 
    const int nPitch = src.GetPitch(); 

    const unsigned int nWidth = src.GetWidth(); 
    const unsigned int nHeight = src.GetHeight(); 
    BYTE * pxPixel = reinterpret_cast<BYTE*>(src.GetBits()); 


    for(int nY = 0; nY < nHeight; ++nY) 
    { 
     for(int nX = 0; nX < nWidth; ++nX) 
     { 
      pxPixel += 3; 
      bright[nX][nY]=((*pxPixel+*(pxPixel+1)+*(pxPixel+2))/3.0)/255.0; 
     }; 

     if(nPitch >= 0) 
      pxPixel += nPitch - (nWidth*3); 
     else 
      pxPixel -= ((nWidth*3) + (nPitch*(-1))); 
    }; 
} 

lumineux est attribué dans le constructeur, son double [500] [500]. En fait, je ne vois pas de fuites de mémoire dans ce code, qu'est-ce que je fais mal?

maintenant des points de débogage à cette ligne:

bright[nX][nY]=((*pxPixel+*(pxPixel+1)+*(pxPixel+2))/3.0)/255.0; 

disant pxPixel est un BadPtr>. < damn je ne comprends pas une chose.

+0

Comment ressemble votre boucle d'itération? –

+0

est-ce un programme multithread? – Naveen

+0

Code ajouté à ma question Multithread? en aucune façon! C'est un programme unique qui fonctionne avec des itérateurs C++, rien d'autre. Il recueille des données, c'est tout. – Anton

Répondre

1

Je n'ai pas regardé votre code, mais cela ressemble à quelqu'un qui écrase les limites de ses données. Pour attraper quelque chose comme ceci:

  • Laissez votre boucle courir jusqu'à la 143ème itération. (Utilisez un point d'arrêt conditionnel pour rompre à la 143ème fois.) Examinez votre dossier pour vous assurer qu'il est toujours correct.
  • Définissez un point d'arrêt de données sur l'adresse de ses données. (Je ne sais pas CString, donc je ne peux pas vous aider là-bas.)
  • Pas à pas dans le code.
  • Lorsque le point d'arrêt de données est atteint, examinez la pile pour savoir ce qui se passe.
+0

CString est une classe MFC. C'est tellement vieux, ça a été fait avant que le STL ne devienne une partie de la langue. Si vous extrayez leur implémentation CArray, elle utilise memcpy pour copier des objets. – Puppy

+0

@DeadMG: Je savais que c'était MFC et je savais que c'était mal conçu. Mais pourquoi le down-vote? – sbi

+0

Et encore plus déroutant: pourquoi ce vote négatif n'apparaît-il pas dans mon onglet réputation? – sbi

Questions connexes