wie kann man zwei buffer speichersparend zusammenfügen?



  • Hi,

    Ich bin im moment vor einem Problem.
    Ich habe zwei Buffer char buf1[100] und char buf2[ca. 921600] , und möchte diese so zusammenfügen, dass am Ende von buf1 buf2 steht. Ich könnte zwar eine temporäres Array mit den addierten größen erstellen, allerdings kommt mir das weder schnell noch platzsparend vor.

    Gibt es eine Möglichkeit das elegant zu lösen?

    LG



  • Dazu müsste man den Speicherbereich vergrößern. Dazu gibt es die Funktion realloc.

    Allerdings bin ich mir nicht sicher, ob man eine Variable mit fester Größe noch umbiegen kann. Vermutlich musst du dann von vornerein mit Zeigern arbeiten.



  • Meines Wissens nach kann realloc Speicherbereiche nicht direkt vergrößern. Intern legt auch er einen größeren Buffer an und kopiert den alten Inhalt in den neuen Buffer.

    Gruß Kimmi



  • jkljkl schrieb:

    Allerdings bin ich mir nicht sicher, ob man eine Variable mit fester Größe noch umbiegen kann. Vermutlich musst du dann von vornerein mit Zeigern arbeiten.

    es klappt nur mit dynamisch allokiertem speicher (malloc oder calloc)

    kimmi schrieb:

    Meines Wissens nach kann realloc Speicherbereiche nicht direkt vergrößern. Intern legt auch er einen größeren Buffer an und kopiert den alten Inhalt in den neuen Buffer.

    das stimmt so nicht, denn falls am ende des speichers noch platz frei ist, so kann dieser vergrößert werden ohne umkopiert zu werden. dieser fall tritt nur ein falls am ende des allokierten speichers kein platz ist und ein ganz neuer bereich der richtigen größe gesucht werden muß.



  • kimmi schrieb:

    Meines Wissens nach kann realloc Speicherbereiche nicht direkt vergrößern. Intern legt auch er einen größeren Buffer an und kopiert den alten Inhalt in den neuen Buffer.

    Darauf läuft's zwar meistens hinaus, heißt aber nicht, daß realloc das nicht kann. realloc() prüft meist, ob der direkt angrenzende Heapblock ausreichend für die anstehende Vergrößerung ist und verzichtet im Positiv- Fall auf das Umkopieren. Wer gesicherte Timings braucht, sollte aber auf realloc verzichten, weil's mal so, mal so kommt.

    Fragesteller0815 schrieb:

    Ich habe zwei Buffer char buf1[100] und char buf2[ca. 921600] , und möchte diese so zusammenfügen, dass am Ende von buf1 buf2 steht. Ich könnte zwar eine temporäres Array mit den addierten größen erstellen, allerdings kommt mir das weder schnell noch platzsparend vor.

    Gibt es eine Möglichkeit das elegant zu lösen?

    Nö, läuft eigentlich immer auf eine zumindest kurzfristige Verdoppelung des benötigten Speichers raus. Am besten die Buffer von Anfang an als ein Block anlegen und die Aufteilung intern per Programmlogik.



  • Denk mal selbst nach: Buffer speichern etwas und brauchen dafür genügend Platz. Will man zwei Buffer zusammenfügen, so braucht man dafür einen Zielbuffer mit der Grösse beider Buffer. Für das Zusammenfügen wird notwendig dieser erweiterte Platz gebraucht. Die einfachste und schnellste Lösung mit ANSI-C bleibt ein deklarierter Zielbuffer in der erforderlichen Grösse. Wohin sollen die zusammengefügten Buffer gelangen? Wenn wir das wissen, kommen wir weiter. Möglichkeiten zur Lösung gibt es genug, auch platzsparende!
    Noch eine Frage: Was beinhalten deine Buffer? Für Strings (char*) gibt es Standard-Lösungen in C++.



  • der kleinere Buffer wird von mir erstellt,der größere allerdings von einer funktion die mir nur einen Zeiger auf ein struct zurückgibt in der der große buffer enthalten ist.
    Die Elemente sind alle vom typ unsigned char
    Ich dachte das es vielleicht eine möglichkeit gibt an den ersten buffer einen pointer zum 2ten anzuhängen. (so dass ich mit einer for-schleife ohne unterbrechung drüber gehen kann)
    Aber anscheinend gibt es keine Möglichkeit das ganze ohne umherkopieren zu lösen 😞

    LG



  • Also wenn das Ding ein Array und Teil eines Structs ist, dann hast du eh keine Chance, weil direkt hinter diesem Array das nächste Element des Structs liegt.

    Falls in dem Struct nur ein Pointer an irgendeine andere Stelle im Speicher zeigt (mit malloc() erzeugt), gibts realloc().



  • Fragesteller0815 schrieb:

    der kleinere Buffer wird von mir erstellt,der größere allerdings von einer funktion die mir nur einen Zeiger auf ein struct zurückgibt in der der große buffer enthalten ist.
    Die Elemente sind alle vom typ unsigned char
    Ich dachte das es vielleicht eine möglichkeit gibt an den ersten buffer einen pointer zum 2ten anzuhängen. (so dass ich mit einer for-schleife ohne unterbrechung drüber gehen kann)
    Aber anscheinend gibt es keine Möglichkeit das ganze ohne umherkopieren zu lösen 😞

    LG

    Die for-Schleife kannst du doch trotzdem machen.

    for (int i = 0; i < SIZE1+SIZE2; i++) {
        do_stuff(i < SIZE1 ? buf1[i] : buf2[i-SIZE1]);
    }
    

    Aber ordentlicher wäre es natürlich, einfach zwei Schleifen zu machen.

    for (int i = 0; i < SIZE1; i++) {
        do_stuff(buf1[i]);
    }
    for (int i = 0; i < SIZE2; i++) {
        do_stuff(buf2[i]);
    }
    

    Jedenfalls würde ich nicht ohne Grund umkopieren!



  • Ich muss umkopieren weil der ganze Buffer (buf1+buf2) an eine Funktion übergeben werden, die prüft ob genug ram übrig ist um den buffer weiter zu verarbeiten.
    Wenn ich aber zuerst buffer1 und dann erst buffer2 übergeben dann kommt natürlich ein blödsinn raus, weil es passieren kann das genug platz für buffer1 ist, aber nicht mehr für buffer2.
    Die beiden gehören aber zusammen, da der kleine buffer die informationen enthält wie der 2te buffer interpretiert werden muss.

    LG



  • boah, sorry für das Deutsch. So schlimm wars auch schon lange nicht mehr -.-



  • du kannst dir auch virtuelle strings anlegen, als bsp.

    typedef struct _myStr{
      char *data;
      struct _myStr *next;
    }myStr;
    
    void printString(myStr *s){
      do{
        printf("%s",s->data);
        s = s->next;
      }while(s);
    }
    
    int main(void){
      myStr a;
      myStr b;
      a.data = "hello"; 
      b.data = " world";
      a.next = &b;
      b.next = 0;
      printString(&a);
      return 0;
    }
    

    so in der richtung 🙂



  • Das Problem dabei ist, dass nicht ich die Funktion geschrieben habe (und diese verlangt eben const char *msg ).

    LG



  • earli schrieb:

    for (int i = 0; i < SIZE1+SIZE2; i++) {
        do_stuff(i < SIZE1 ? buf1[i] : buf2[i-SIZE1]);
    }
    

    wenn du weißt wie es geht, dann post doch bitte nicht sowas! 🙄



  • Fragesteller0815 schrieb:

    Ich muss umkopieren weil der ganze Buffer (buf1+buf2) an eine Funktion übergeben werden, die prüft ob genug ram übrig ist um den buffer weiter zu verarbeiten.
    Wenn ich aber zuerst buffer1 und dann erst buffer2 übergeben dann kommt natürlich ein blödsinn raus, weil es passieren kann das genug platz für buffer1 ist, aber nicht mehr für buffer2.

    Was kannst Du denn Deiner Pufferüberprüfungsfunktion übergeben und was liefert die zurück?



  • Die Funktion sieht so aus: bool sendMsg(const char *toSend, const int len) und die liefert eben false zurück wenn nicht genug speicher da is.



  • Konntest du das Problem inzwischen lösen?



  • Fragesteller0815 schrieb:

    Ich bin im moment vor einem Problem.
    Ich habe zwei Buffer char buf1[100] und char buf2[ca. 921600] , und möchte diese so zusammenfügen, dass am Ende von buf1 buf2 steht. Ich könnte zwar eine temporäres Array mit den addierten größen erstellen, allerdings kommt mir das weder schnell noch platzsparend vor.
    Gibt es eine Möglichkeit das elegant zu lösen?

    Ja, Du benutzt einfach von vorn herein nur einen Puffer und machst es so:

    char gesamt[100+921600];
    char *buff1 = gesamt;
    char *buff2 = gesamt + 100;
    

    Damit liegen beide Speicherbereiche direkt hintereinander. Du brauchst nichts zu kopieren und verschwendest keinen Speicher.
    Überall wo Du bisher buff1 und buff2 benutzt hast, nimmst Du nun die Pointer.



  • Das ist etwas off-topic, aber eigentlich ist dein Projekt schon irgendwie verkorkst, dass es überhaupt 1-Mio-elementige Arrays gibt. Ihr solltet euch vielleicht eine andere Repräsentation der Daten überlegen.



  • earli schrieb:

    Das ist etwas off-topic, aber eigentlich ist dein Projekt schon irgendwie verkorkst, dass es überhaupt 1-Mio-elementige Arrays gibt. Ihr solltet euch vielleicht eine andere Repräsentation der Daten überlegen.

    das ist nicht nur off-topic, sondern auch eine haltlose vermutung, woher willst du wissen mit was für daten die jonglieren müssen?

    auch hier im forum gilt der grundsatz „in dubio pro reo“
    😃

    lg lolo


Log in to reply