Beschädigung des Heaps?



  • Hallo,
    ich habe ein merkwürdiges Problem:
    Mein Programm stürzt immer an anderen Stellen(je nachdem was ich für Parameter bei der Funktion übergebe) mit folgender Fehlermeldung ab.

    Windwos hat einen Haltepunkt ausgelöst.
    Dies kann auf eine Bescädigung des Heaps zurückzuführen zu sein, die auf ein Problem in ssbb.exe oder in einer der geladenen DLLs hinweist.

    Die Funktion sieht so aus:(ich habe die Stellen an denen er abstürzt markiert und den Funktionparameter w, bei dem es an der Stelle passiert, dazu geschrieben. p und h=10 bleiben immer gleich)

    COLORREF TableReader::GetFontColor(POINT p, short w, short h){
    	MeasureDuration dura;
    
    	hdc = GetDC(hwnd);
    	HDC _2hdc = CreateCompatibleDC(this->hdc);//HDC to put the hidden window in
    	HBITMAP hbmp = CreateCompatibleBitmap(hdc,p.x+w+2,p.y+h+30);
    
    	SelectObject(_2hdc,hbmp);
    	PrintWindow(hwnd,_2hdc,0);
    
    	HDC hdcMem = CreateCompatibleDC(_2hdc);//hdc to copy the needed part of the hidden window in(stored in _2hdc)
    	HBITMAP hbmp2 = CreateCompatibleBitmap(_2hdc,w,h);//bmp with hidden window
    	SelectObject(hdcMem, hbmp2);
    	BitBlt(hdcMem, 0,0,w,h, _2hdc, p.x+2,p.y+30, SRCCOPY);
    
    	byte BytePerPixel =3;
    	byte* bBytes;
    	bBytes= new byte[w*h*BytePerPixel];
          BITMAPINFO* bmInfo = new BITMAPINFO();				
          bmInfo->bmiHeader.biSize = 40;
          bmInfo->bmiHeader.biWidth = w;
          bmInfo->bmiHeader.biHeight = h;
          bmInfo->bmiHeader.biPlanes = 1;
          bmInfo->bmiHeader.biBitCount = BytePerPixel*8;
          bmInfo->bmiHeader.biCompression = BI_RGB;
          bmInfo->bmiHeader.biSizeImage = 0;
          bmInfo->bmiHeader.biXPelsPerMeter = 0;
          bmInfo->bmiHeader.biYPelsPerMeter = 0;
          bmInfo->bmiHeader.biClrUsed = 0;
          bmInfo->bmiHeader.biClrImportant = 0;
    
    	GetDIBits(hdcMem, hbmp2, 0,h, bBytes, bmInfo, DIB_RGB_COLORS);
    	DeleteObject(hbmp);
    	DeleteObject(hbmp2);
    
    	long reds=0, greens=0, blues=0;
    	int totalCount=0;
    
    	short arrsize=100, curMax=-1;
    	ColorCount curColor;
    	short *colorCount=NULL;
    	COLORREF* colors=NULL;
    	colors = new COLORREF[arrsize]; //<<----- stürzt ab bei w=51
    	colorCount = new short[arrsize];
    
    	for(int i=0; i<arrsize; i++)
    	{
    		colors[i]=0;
    		colorCount[i]=0;
    	}
    
    	long totalPixelCount =0;
    	for(short y=0; y<h; y++)	
    		for(short x=0; x<w; x++){
    			int pos = y*w*BytePerPixel+x*BytePerPixel;
    			curColor.color = RGB(bBytes[pos+2],bBytes[pos+1],bBytes[pos+0]);
    			bool found;
    			found= false;
    			for(int i=0; i<arrsize; i++){
    				totalPixelCount++;
    				if(curColor.color == colors[i]){
    					colorCount[i]++;
    					found = true;
    					curMax = i;
    					break;
    				}	
    			}
    
    			if(!found){
    				if(curMax+1>=arrsize){////Expand the array
    					arrsize+=100;
    					short *tempCount=NULL;
    					tempCount = new short[arrsize];
    					COLORREF* tempColors=NULL;
    					tempColors= new COLORREF[arrsize];
    
    					for (int i=0; i<=curMax; i++) {//copy array content
    						tempCount[i] = colorCount[i]; 
    						tempColors[i] = colors[i];						
    					}
    					delete [] colors;
    					delete [] colorCount;
    					colors = tempColors;
    					colorCount= tempCount;
    					for (int i=curMax; i<arrsize;i++){
    						colors[i]=0;
    						colorCount[i]=0;
    					}
    				}
    				curMax++;
    				curColor.count = 1;
    				colors[curMax] =curColor.color;
    				colorCount[curMax]=1;
    			}
    
    			reds+=GetRValue(curColor.color);
    			greens+=GetGValue(curColor.color);
    			blues+=GetBValue(curColor.color);
    			totalCount++;
    		}
    	if(curMax==1)
    	{		
    		if(colorCount[0]>colorCount[1])
    			return colors[1];
    		else return colors[0];
    	}
    	COLORREF colortest=RGB(125,50,200);
    	double red_avg, green_avg, blue_avg;
    	red_avg = reds/totalCount;
    	green_avg = greens/totalCount;
    	blue_avg = blues/totalCount;
    
    	DWORD red, green, blue;
    	double diff=0,maxDiff=0;
    	COLORREF fontColor=0;
    
    	for(int i=0; i<=curMax; i++){
    		red=GetRValue(colors[i]);
    		green=GetGValue(colors[i]);
    		blue=GetBValue(colors[i]);
    		diff = abs(red-red_avg)+abs(green-green_avg)+abs(blue-blue_avg);
    		if(diff>maxDiff){
    			maxDiff = diff;
    			fontColor = colors[i];
    		}
    	}
    
    	DeleteDC(_2hdc);
    	DeleteDC(hdcMem);
    	delete [] colorCount;
    	delete [] colors;
    	delete [] bBytes; //<<----- stürzt ab bei w=61 oder w=30
    
    	return fontColor;
    }
    

    Bei w=20 oder w=120 stürzt er z.b. nicht ab.
    Gibt natürlich noch mehr Kombinationen, wo er abstürzt oder nicht.

    Jemand eine Idee, woran das liegt? Ich denke ja, ich reservie und/oder gebe den Speicher falsch frei.

    Danke im voraus
    veio



  • ich hab keine ahnung was es sein kann, aber wäre es wirklich möglich (ich hab keinen plan!), dass du dir den heap zerschossen hast?!



  • das geht?^^



  • Achja, ich sehe gerade bei w=51 ist es eine andere Fehlermeldung:

    Eine nicht behandelte Ausnahme des Typs "System.Runtime.InteropServices.SEhExpception" ist in sspb.exe aufgetreten.

    Zusätzliche Informationen: Eine externe Komponente hat eine Ausnahme ausgelöst.

    lf help 😞



  • Jetzt ist dein Heap hin und du muss dir nen neuen kaufen. :p

    Du schreibst wahrscheinlich irgendwo über arraygerenzen raus.



  • Nutzt du Threads?
    Ne andere Lösung fällt mir da echt nicht ein...
    "Eine externe Komponente hat eine Ausnahme ausgelöst." => iwo musst du wo nen try-catch drumpacken, kann das sein?



  • ne, ist single threaded.
    und keine ahnung, wo ich da nen try catch block einbinden sollte.



  • Schräges Problem..

    Dazu fällt mir nur das ein:

    "Wenn der RAM leuchtet und brennt, der Programmierer aus dem Zimmer rennt." 😃



  • also wenn du die zeilen weglässt geht es auch mit den werten? ich glaube nämlich noch nicht daran ;P

    //edit:
    hat leider nix damit zu tun... ^^

    short *colorCount=NULL; //wieso?
        COLORREF* colors=NULL; //wieso?
        colors = new COLORREF[arrsize];
        colorCount = new short[arrsize]; 
    /*
        short *colorCount = new COLORREF[arrsize]; //<<----- stürzt ab bei w=51 
        COLORREF* colors = new short[arrsize]; 
    */
    


  • unskilled schrieb:

    also wenn du die zeilen weglässt geht es auch mit den werten? ich glaube nämlich noch nicht daran ;P

    //edit:
    hat leider nix damit zu tun... ^^

    short *colorCount=NULL; //wieso?
        COLORREF* colors=NULL; //wieso?
        colors = new COLORREF[arrsize];
        colorCount = new short[arrsize]; 
    /*
        short *colorCount = new COLORREF[arrsize]; //<<----- stürzt ab bei w=51 
        COLORREF* colors = new short[arrsize]; 
    */
    

    Wenn ich das und alles was mit colors und colorCount zusammenhängt auskommentiere, stürzt er wie bei den anderen Werten bei "delete [] bBytes" ab.



  • Hallo

    Der Speicher für die Bitmap ist zu klein. Jede Zeile der Bitmap beginnt an einer durch 4 teilbaren Adresse. Falls nötig werden dummy-Bytes eingefügt, für die du keinen Speicher reserviert hast.
    So müsste es funktionieren:

    bBytes= new byte[((w*BytePerPixel+3)&~3)*h];
    

    Gruss Chris



  • ich meinte, du solltest erst ma nur das delete auskommentieren und sagen, obs dann geht ^^ aber anscheind is jz dein prob eh gelöst ^^



  • bislang konnt ich das Programm mit der Änderung nicht zum abstürzen bringen...scheint also des Rätsels Lösung zu sein.
    Danke!


Anmelden zum Antworten