Problem mit Heap Corruption



  • Hallo ihr lieben,

    ich stelle mich mal kurz vor, da das hier mein erster Post in eurem Forum ist. Mein Name ist Mats, ich komme aus der Nähe von Hamburg, bin 27 und beruflich als Techniker beim Fernsehen unterwegs. Seit meiner Jugend beschäftige ich mich hobby-mäßig mit programmierung, habe mich aber mehr mit Sprachen wie PHP beschäftigt.

    Jetzt stehe ich vor einer großen Herausforderung, die ich hoffentlich noch gewuppt kriege. Jetzt zu meiner Problematik:

    Bei einem Volleyballspiel werden alle Statistiken mittels der Software "Datavolley" erfasst und in irgendeiner Datenbank gespeichert. Diese Daten möchte ich gerne nutzen um sie in unser TV-Grafiksystem zu speisen.

    Zum Auslesen der Daten habe ich von dem Hersteller der Datavolley-Software ein paar Daten bekommen. Unter anderem eine Rundll.exe die einem die Daten in einem Fenster ausspuckt. Anbei ist auch noch ein Code und eine .dll mit dem man arbeiten kann / soll.

    Da ich diese Daten einfach in einer Textdatei brauche, um sie dann wieder mit meiner Grafiksoftware lesen zu können, dachte ich mir, ich probiere es mal aus.

    Darauf hin habe ich mir Virtual Studio C++ Express heruntergeladen und einfach mal den Code da reingeklatscht. Das kompilierte Programm lässt sich in der Konsole ausführen. Schreibt mir auch die Werte in die Konsole, kommt dann aber mit der Meldung:

    Debug error:

    Programmpfad

    HEAP CORRUPTION DETECTED after normal block .....
    CRT detected that the application wrote to memory after end of heap buffer.

    Ich hoffe sehr, dass ihr mein Problem versteht. Sonst fragt bitte einfach. Brauche das Ganze am kommenden Wochenende und da die Funktion ja bereits gegeben ist stört eigentlich nur die Fehlermeldung.
    Ich bedanke mich schonmal ganz herzlich für all eure Hilfe!

    Lieben Gruß
    Mats

    Anbei noch mein Code.

    // SampleDLL.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include "windows.h"
    #include "stdio.h"
    
    typedef struct TDVParamsStruct {
    	char *PathSource;	// Path containing STATISTICS*.TOT
        	int	IdTeam;		// 0=Home, 1=Visitor
        	int 	IdPlayer;	// 0..99 Player Jersey Number, 100=Team, 101..106 Rotation 1..6
      	int 	Skill;		// 0=Tot, 1=Serve, 2=Reception, 3=Attack, 4=Block, 5=Dig, 6=Set, 7=Free Ball
    	int	SetN;		// 0=Match, 1..5 Set
        	int	IDCall;		// 0=Fixed value
    } TDVParams;
    
    typedef struct TDVOutPtsErrStruct {
      	int Pts;		// Points
        	int Err;		// Errors
        	int Tot;		// Total events
    } *TDVOutPtsErr;
    
    typedef UINT (CALLBACK* LPFNDLLFUNC1)(TDVParams, TDVOutPtsErr);
    
    int main(int argc, char* argv[])
    {
    	printf("an");
    	TDVParams Par;
    	TDVOutPtsErr ParFunc = NULL;
    	ParFunc = (TDVOutPtsErr) malloc(sizeof(TDVOutPtsErr));
    	char par[36] = "C:/";	// Path containing dv3STATISTICS*.tot
    
    	Par.PathSource = par;
    	Par.IdPlayer = 100;
    	Par.IdTeam = 0;
    	Par.SetN = 0;
    	Par.Skill = 0;
    
    	HINSTANCE hDLL;               // Handle to DLL
    	LPFNDLLFUNC1 GetPointsErr;    // Function pointer
    
    	UINT uReturnVal;
    
    	hDLL = LoadLibrary("DvStat.dll");
    	if (hDLL != NULL)
    	{
    		GetPointsErr = (LPFNDLLFUNC1)GetProcAddress(hDLL,"GetPointsErr");
    		if (!GetPointsErr)
    		{
    			// handle the error
    			FreeLibrary(hDLL);
    			free(ParFunc);
    			return -1;
    		}
    		else
    		{
    
    			// call the function
    			uReturnVal = GetPointsErr(Par, ParFunc);
    
    			printf("Return = %d \n", uReturnVal);
    
    			if (uReturnVal == 0){
    				//Print Output
    				printf("Tot: %d \n", ParFunc->Tot);
    				printf("Err: %d \n", ParFunc->Err);
    				printf("Points: %d \n", ParFunc->Pts);			
    			}
    			else
    			{
    				printf("Error");
    				FreeLibrary(hDLL);
    				free(ParFunc);
    				return -1;
    			}
    		}
    	}
    
    	FreeLibrary(hDLL);
    
    	free(ParFunc);
    	//return 0;
    }
    


  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum C (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Das ist alles Beispielcode des Herstellers oder hast du da etwas verändert?

    Im Zweifelsfall hast du Release und Debug vermischt, d.h. DLL ist als Release übersetzt, das Programm dann aber als Debug gebaut.


  • Mod

    Zeile 33 ist schon mal Quatsch. Weder ist sizeof(TDVOutPtsErr) die korrekte Größe für das, was hinterher gemacht wird, noch ist das malloc/free hier überhaupt angebracht. Das hat wohl irgendein Praktikant, der noch nie C (das ist C, kein C++) gemacht hat in der Mittagspause zusammen geschustert.

    Da ich die Bibliothek nicht haben, kann ich es nicht testen. Noch habe ich die Spezifikationen der Bibliothek, so dass ich nur raten kann. Aber so mal fix über den Code gegangen, so dass er halbwegs richtig aussieht, würde ich folgendes ausprobieren:

    // Die Datei nennen wir lieber SampleDLL.c, dann erkennt MSVC auch, dass dies C sein soll.
    
    #include "stdafx.h"
    #include "windows.h"
    #include "stdio.h"
    
    typedef struct TDVParamsStruct {
      char *PathSource;
      int IdTeam;     
      int IdPlayer;   
      int Skill;  
      int SetN; 
      int IDCall;
    } TDVParams;
    
    typedef struct TDVOutPtsErrStruct {
      int Pts; 
      int Err; 
      int Tot;  
    } TDVOutPtsErr;  // Kein '*'
    
    typedef UINT (CALLBACK* LPFNDLLFUNC1)(TDVParams, TDVOutPtsErr*); // Dafür hier ein '*'
    
    int main()  // Wenn wir die Parameter nicht nutzen, führen wir sie gar nicht erst ein
    {
      HINSTANCE hDLL = LoadLibrary("DvStat.dll");  // In C müssen Variablen am Anfang des Scopes definiert werden
      printf("an");  // Niedlich
    
      if (hDLL != NULL)
        {
          LPFNDLLFUNC1 GetPointsErr = (LPFNDLLFUNC1)GetProcAddress(hDLL,"GetPointsErr");  // Variablen so lokal wie möglich
          if (!GetPointsErr)
            {
              FreeLibrary(hDLL);
              // free braucht's nun nicht mehr
              return -1;
            }
          else
            {
              TDVParams Par;        // Variablen so lokal wie möglich
              TDVOutPtsErr ParFunc; // Einfach eine normale Variable
              UINT uReturnVal;
    
              char par[36] = "C:/";
    
              // Folgendes ginge auch geschickter, aber ich will nicht alles umschreiben
              Par.PathSource = par;  
              Par.IdPlayer = 100;
              Par.IdTeam = 0;
              Par.SetN = 0;
              Par.Skill = 0;
    
              uReturnVal = GetPointsErr(Par, &ParFunc); // Dann eben hier einen Zeiger auf die Variable übergeben
    
              printf("Return = %d \n", uReturnVal);
    
              if (uReturnVal == 0){
                printf("Tot: %d \n", ParFunc.Tot);  // hier . statt ->, da wir keinen Zeiger mehr vorliegen haben
                printf("Err: %d \n", ParFunc.Err);
                printf("Points: %d \n", ParFunc.Pts);         
              }
              else
                {
                  printf("Error");
                  FreeLibrary(hDLL);
                  // Hier natürlich auch kein free
                  return -1;
                }
            }
        }
    
      FreeLibrary(hDLL);
      // Und hier auch nicht
      return 0;  // In C(89) ist return 0 kein default, wir müssen es schon angeben.
    }
    

    Die vielen freeLibrarys sind noch etwas ungeschickt, aber ich wollte jetzt nicht alles neu schreiben.



  • Vielen Dank ihr lieben! Vor Allem an SeppJ.

    Leider fehlt mir die nötige Kompetenz um Deine Änderungen im Detail nachvollziehen zu können, aber auf jeden Fall läuft das Ganze jetzt ohne Fehler.

    Eventuell sollte ich Dir mal den Kontakt schicken und die verkaufst das reparierte Script an die Pfeifen. :p

    Ich werde mich jetzt etwas in C schlau machen um noch die Dateiausgabe und einen Timer zu realisieren. Ich hoffe ich bekomme das hin, sonst gehe ich euch nochmal auf den Senkel.

    Vielen Dank für die schnelle Hilfe. Tolle Forum!

    Gruß
    Mats


Anmelden zum Antworten