Zeiger an bestimmter Adresse speichern.



  • Hallo,

    ich möchte gerne einen Pointer an einer bestimmten Adresse eines vorher allokierten Speicherbereichs ablegen. Also ich habe irgendwo einen Zeiger auf dem ich die Anfangsadresse meines allkoierten Speicherbereichs ablege:

    char* mem = (char*) malloc(fixedMemory * sizeof(char*));
    

    nun möchte ich am Anfang des Speicherfeldes einen Zeiger ablegen und diesen Block in gleichgroße Abschnitte aufteilen, so dass theoretisch in jedem Block genug Platz ist um zumindest einen Zeiger zu hinterlegen.

    Dafür habe ich mir ein Array angelegt welches so lange ist wie Anzahl der möglichen Blöcke die in das allokierte Speicherbereich passen.

    char *blocks[number]
    

    Leider weiß ich nicht wie ich jetzt dem Array sagen kann, dass es an dieser speziellen Stelle gespeichert werden soll. (Wenn das nicht geht würde es mir auch schon reichen, wenn ich es hinbekomme, dass ich einen Zeiger auf der Adresse auf die *mem zeigt ablegen kann und dann auch entsprechend auf den Nachfolgeadressen.)

    Zusammenfassung:
    Ich habe Zugriff auf einen Speicherbereich und auf dessen Größe und will diesen in gleichgroße Abschnitte aufteilen. Wobei in jeden Abschnitt mindestens ein Zeiger passen muss also 4/8 Byte mindestens pro Block.
    Ich möchte gerne Wissen wie man einen Zeiger an einer bestimmten Adresse speichert. (bzw. ein Array)

    Ich hoffe ihr könnt mir helfen.

    Mit freundlichen Grüßen
    Komisch



  • Wenn du ein dynamisch alloziiertes Array aus Zeigern willst, geht das so:

    char** blocks=new char*[number];
    

    Bzw. in C++ eigentlich so:

    std::vector<char*> blocks(number);
    

    Wenn du schon einen Speicherblock hast und den aus welchen Gründen auch immer umdichten willst:

    char** blocks=reinterpret_cast<char**>(mem);
    


  • Ich denke dabei zuerst an

    struct Block
    {
         Block* next;
         void* data[511];
    };
    
    Block* frontBlock=new Block;
    size_t usedInFrontBlock=0;
    
    for(int i=0;i!=ganzViel;++i)
    {
      if(usedInFrontBlock==511)
      {
        Block* nb=new Block;
        nb->next=frontBlock;
        frontBlock=nb;
        usedInFrontBlock=0;
      }
      frontBlock->data[usedInFrontBlock]=createThingie(cos(i*relativeHumidityOfMoon()/4));
      ++usedInFrontBlock;
    }
    


  • Ich empfehle dringend, das Problem zu vertagen, bis es akut wird. Dann liegt mehr Erfahrung vor, was wirklich gebraucht wird.



  • Danke für die Antworten, aber ich bin mir nicht ganz sicher ob es so genau, dass trifft was ich versuche zu machen.

    Mein Ziel ist es in einem zuvor allokierten Speicherbereich eine Freiblockliste anzulegen. Der Speicherbereich wird zuvor in gleichgroße Blöcke aufgeteilt. Dabei möchte ich den Zeiger auf den ersten freien Block des Speicherbereichs am Anfang des selbigen speichern (so finde ich den Anfang immer wieder). Die anderen Zeiger werden dann anschließend in den Löchern gespeichert also in den freien Speicherbereichen.
    Der Startzeiger zeigt also am Anfang auf den ersten freien Block und dort direkt auf den Zeiger zum nächsten Block. Dieser verweist auf den nächsten und so weiter. Wenn ein Block allokiert wird, wird die Referenz aus der Liste gelöscht.

    Anfangs wollte ich es einfach lösen, in dem ich immer am Anfang jeden Blockes die Adresse des nächsten Blocks eintrage, allerdings soll es wohl einfacher machbar sein.

    Wie würdet ihr da rangehen? Danke schonmal für die Hilfe.

    PS.: reinterpret_cast<char**> erzeugt das ding ein Array oder was macht das genau Converts between types by reinterpreting the underlying bit pattern. Heißt das, dass ich für mein Array dann folgendes machen muss:

    char** blocks=reinterpret_cast<char**>(mem);
    blocks=new char*[number];
    


  • Ich weiß nicht was ihr unter akut versteht, ich (bzw. wir (ich und ein Freund)) versuchen seit einigen Tagen in Zeitstunden ~30h das Problem zu lösen.

    Es gibt eine Klasse Memory die mit malloc einen Speicherbereich allokiert, ein Objekt der Klasse wird an unser Heap Objekt der Klasse Heap übergeben. Diese hat die Aufgabe mit einem Zeiger auf den Anfang des Speicherbereichs (der in Memory allokierte) und der Information über die Größe diesen in gleichgroße Blöcke zu zerlegen und die Blöcke zu verketten. Wobei der Zeiger auf den ersten Block am Anfang des Speichers (von Memory) gespeichert wird. Die Blockgrößen werden von der aufrufenden Klasse festgelegt, allerdings sind alle Blöcke gleich groß (und sollten vermutlich mindestens so groß sein, dass mindestens eine Adresse/ein Zeiger hinein passt). Wenn nun ein Block über die Funktion alloc der Klasse Heap angefordert wird, wird geprüft ob dieser kleiner gleich der eingestellten Blockgröße ist. Ist dies der Fall wird der Speicher aus der Liste entfernt und dem Nutzer übergeben.

    Ich komme allerdings nicht damit klar in den von Memory allokierten Speicher zu schreiben. Entweder bekomme ich irgendwelche Segfaults oder irgendwelche Cast-Probleme mit Zeigern weil ich da irgendwelche Kunststücke probiere (siehe oben).

    Es wäre nett wenn mir vllt einen verständlichen nicht optimalen Weg aufzeigen könntet mein Problem zu lösen.

    Danke im Voraus. (Im Moment versuchen wir mit herumraten und dem lesen verschiedener Guides, gucken von Tutorial etc. einen zu finden der uns speziell hier hilft... bisher erfolglos, wäre echt toll wenn ihr vielleicht einfach erläutern könntet wie man hier vorgeht)

    MfG
    Komisch



  • Netter Plan. Besonders hübsch daran finde ich, daß die Verkettung der Blöcke nur für die in Reserve stehenden Blöcke nötig ist. Von der main() allokierte Blöcke können von der main() ruhig komplett beschrieben werden, denn die Verzeigerung muss erst wieder aufgebaut werden, wenn die main() die Blöcke (per Aufruf von freeBlock) zurück auf die Reservebank schickt.

    #include <cstdlib>
    #include <vector>
    #include <iostream>
    using namespace std;
    
    //das folgende da wären wohl attribute des heaps, hier am beispiel 
    //des theGlobalHeapForSize10. 
    int const bigSize=8192;//großer Speicherbereich, der noch in Blöcke zerlegt wird
    int const blockSize=10;//Jeder Block ist 10 Bytes groß
    char* firstFreeBlock=0;//char*, weil dann Zeigeraritmetik einfacher wird
    char* speicher;
    
    void* allocBlock(){
        if(firstFreeBlock==0){//aus Faulheit nicht in eigene Funktion ausgelagert
            speicher=static_cast<char*>(malloc(bigSize));
            for(char* p=speicher;p<=speicher+bigSize-2*blockSize;p+=blockSize){
                *reinterpret_cast<char**>(p)=p+blockSize;
            }
            *reinterpret_cast<char**>(speicher+bigSize-blockSize)=0;
            firstFreeBlock=speicher;
        }
        char* result=firstFreeBlock;
        firstFreeBlock=*reinterpret_cast<char**>(firstFreeBlock);
        return result;
    }
    void freeBlock(void* p){
        *reinterpret_cast<char**>(p)=firstFreeBlock;
        firstFreeBlock=static_cast<char*>(p);
        //TODO: wenn alle Blöcke eines Speichers zurück sind, den ganzen
        //Speicher mit free zurückgeben?
    }
    
    int main(){
        for(int o=0;o!=2;++o){
            vector<int*> v;
            for(int i=0;i!=10;++i){
                int* p=static_cast<int*>(allocBlock());
                *p=i*i;
                cout<<p<<' '<<*p<<'\n';
                v.push_back(p);
            }
            cout<<'\n';
    
            for(int i=0;i!=10;++i){
                int* p=v[i];
                cout<<p<<' '<<*p<<'\n';
                freeBlock(p);
            }
            cout<<'\n';
        }
    }
    

    Ausgabe

    0x604010 0
    0x60401a 1
    0x604024 4
    0x60402e 9
    0x604038 16
    0x604042 25
    0x60404c 36
    0x604056 49
    0x604060 64
    0x60406a 81
    
    0x604010 0
    0x60401a 1
    0x604024 4
    0x60402e 9
    0x604038 16
    0x604042 25
    0x60404c 36
    0x604056 49
    0x604060 64
    0x60406a 81
    
    0x60406a 0
    0x604060 1
    0x604056 4
    0x60404c 9
    0x604042 16
    0x604038 25
    0x60402e 36
    0x604024 49
    0x60401a 64
    0x604010 81
    
    0x60406a 0
    0x604060 1
    0x604056 4
    0x60404c 9
    0x604042 16
    0x604038 25
    0x60402e 36
    0x604024 49
    0x60401a 64
    0x604010 81
    


  • Vielen Dank, sorry das ich mich so spät bedanke, aber nach dem ich durch deine/ihre Hilfe gestern endlich weiter kam war ich erstmal gut beschäftigt bis 2 Uhr nachts.^^

    Ich hab halt wenig Ahnung von C++ und ich hab zwar Tanenbaum gelesen zu Betriebssystemen aber an der Implementierung von Strategien scheitere ich leider die ganze Zeit.


Anmelden zum Antworten