"Logikfrage": Zugriff auf bestimmte Bereiche



  • Hallo.
    Ich suche derzeit nach einer Möglichkeit um folgendes Problem zu lösen.
    Die Ausgangslage ist die, dass ich im Programm von bestimmten Bereichen bestimmte Werte speichere - momentan läuft das über ein Struct und einen std::vector was vermutlich nicht die beste Lösung ist. Ich zeige das mal anhand eines Beispiels:

    struct Range
    {
    	unsigned long Start;
    	int Size;
    	char *Data;
    };
    
    // ...
    
    std::vector<Range*> Ranges;
    
    void AddRange(unsigned long Start, int Size, char *Data)
    {
    	Range *pRange = new Range;
    	Range->Start = Start;
    	Range->Size = Size;
    	Range->Data = Data;
    
    	Ranges.push_back(pRange);
    }
    
    // Beispielhafte Ranges hinzufügen:
    AddRange(5000, 10, "\x00\x29\x84\x02\x85\x82\x10\x48\x85\x91");
    AddRange(200, 10, "\x10\x39\x94\x22\x95\x42\x50\x28\x95\x31");
    AddRange(99999, 10, "\x20\x49\x04\x32\x05\x12\x80\x58\x65\x01");
    

    Die Art der Speicherung ist für mein Problem glaube ich nicht so geeignet, was besseres kenne ich dafür jedoch nicht. Diese "Bereiche" werden nun im Programm gespeichert und Plugins sollen darauf zugreifen können. Gedacht habe ich mir das so:

    // Zugriffsfunktion
    bool GetRangeData(unsigned long Start, int Size, char *Data)
    {
    	for (std::vector<Range*>::iterator it = Ranges.begin(); it != Ranges.end(); it++)
    	{
    		Range *pRange = (*it);
    		int Begin = -1;
    		int End = -1;
    
    		// "Kollisions"-Abfrage?
    		// -> Ist der abgefragte Bereich überhaupt gespeichert?
    
    		// Fall 1: Start ist auf jedenfall vorhanden
    		if (pRange->Start >= Start && pRange->Start < (Start + Size))
    		{
    			Begin = abs(pRange->Start - Start);
    
    			if (pRange->Start + pRange->Size <= (Start + Size))
    			{
    				End = Begin + Size;
    			}
    			else
    			{
    				End = Begin + Size - ((pRange->Start + pRange->Size) - (Start + Size));
    			}
    		}
    		// Fall 2: Start unterhalb, aber pRange->Size "ragt hinein"
    		else if (pRange->Start < Start && (pRange->Start + pRange->Size) >= Start)
    		{
    			Begin = 0;
    			End = (pRange->Start + pRange->Size) - (Start + Size);
    		}
    
    		// Fund?
    		if (Begin != -1 && End != -1)
    		{
    			// Kopieren
    			memcpy(Data, pRange + Begin, End);
    			return true;
    		}
    	}
    
    	return false;
    }
    

    Wie man sieht sieht die Funktion nicht gerade sehr schön aus und ich bin mir auch verdammt unsicher, ob...
    a) die Logik dahinter soweit stimmt
    b) alle Fälle abgedeckt sind

    Hier mal ein paar Beispielhafte Zugriffe inklusive der gewollten Resultate:

    // Zugriff
    char *pData = new char[10];
    
    if (GetRangeData(5000, 10, pData))
    {
    	//AddRange(5000, 10, "\x00\x29\x84\x02\x85\x82\x10\x48\x85\x91");
    	// pData sollte "\x00\x29\x84\x02\x85\x82\x10\x48\x85\x91" sein
    }
    
    if (GetRangeData(5005, 10, pData))
    {
    	//AddRange(5000, 10, "\x00\x29\x84\x02\x85\x82\x10\x48\x85\x91");
    	// pData sollte "\x82\x10\x48\x85\x91" sein
    }
    
    if (GetRangeData(195, 10, pData))
    {
    	//AddRange(200, 10, "\x10\x39\x94\x22\x95\x42\x50\x28\x95\x31");
    	// pData sollte "\x42\x50\x28\x95\x31" sein
    }
    
    if (GetRangeData(100000, 10, pData))
    {
    	//AddRange(99999, 10, "\x20\x49\x04\x32\x05\x12\x80\x58\x65\x01");
    	// pData sollte "x49\x04\x32\x05\x12\x80\x58\x65\x01" sein
    }
    

    Ich hoffe jemand versteht das Problem 🙂
    Gruß & Danke



  • std::vector<Range*> Ranges;
    

    Betrifft zwar nicht dein Problem, aber verzichte hier besser auf Zeiger. Zum Beispiel hättest du so keine Memory Leaks.

    memcpy(Data, pRange + Begin, End);
    

    Schau dir auf www.cplusplus.com nochmal die Signatur von std::memcpy() an. Der dritte Parameter bezeichnet nicht das Ende. Ausserdem wäre std::copy() vielleicht besser.

    Aber ich verstehe deinen Code nicht ganz. Willst du lediglich prüfen, ob ein Bereich bereits besetzt ist?



  • Ja, das will ich prüfen.
    Werde ich mir anschauen.

    End ist in dem Falle auch nicht das Ende sondern die Länge, etwas doof benannt, stimmt.

    Gruß


Anmelden zum Antworten