Größe eines Rinpuffer in C



  • Moin,

    ich wollte mal frage, ob zufällig jemand weiß, wie ich aus einem Ringpuffer mit einem Lese- und einem Schreibzeiger die Größe des noch freien Speichers bekomme.
    Wenn ich z.B.
    char Lesezeiger,Schreibzeiger, buffer[1024];
    wie kann ich dann herausfinden, wieviel Speicher noch in meinem Array zum beschreiben frei sind.
    Es soll gelten: Wenn Schreibzeiger > Lesezeiger dann ist
    Gesamtanzahl Bytes(hier die 1024) - |Schreibzeiger - Lesezeiger)| == freier Speicher
    Schreibzeiger < Lesezeiger dann ist |Schreibzeiger - Lesezeiger|== freier Speicher

    Hat jemand eine Idee wie ich das realisieren kann ?



  • welche methoden hast du schon probiert und funktionieren diese oder nicht?



  • bisher noch keine 🙂



  • cyper schrieb:

    Es soll gelten: Wenn Schreibzeiger > Lesezeiger dann ist
    Gesamtanzahl Bytes(hier die 1024) - |Schreibzeiger - Lesezeiger)| == freier Speicher
    Schreibzeiger < Lesezeiger dann ist |Schreibzeiger - Lesezeiger|== freier Speicher

    Hat jemand eine Idee wie ich das realisieren kann ?

    Genau so, wie du es dort geschrieben hast (eventuell noch die Betragsstriche auflösen:

    if(wr>rd)
      space = buf_size - (wr-rd);
    else if(wr<rd)
      space = (rd-wr);
    else //wr==rd
      space = /*überrundet?*/ ? 0 : 1024;
    

    Hmm, wenn ich mir das recht überlege, kann man das sogar noch zusammenfassen:

    space = (/*überrundet?*/ ? 0 : 1024) + (rd-wr);
    


  • du könntest auch bei jeder schreib/leseoperation einen zähler rauf/runterzählen. das macht alles sehr viel einfacher. den zähler kannste auch benutzen um festzustellen ob der buffer leer bzw. voll ist



  • schonmal thx für die Antworten

    ich hatte mir das so gedacht:

    char writebuff[1024],*read_ptr, *write_ptr;
    
    int buff_free(){
    if(position(write_ptr) > position(read_ptr))
        return sizeof(writebuff) - abs(position(write_ptr) - position(read_ptr);
    else if(position(write_ptr) < position(read_ptr))
        return abs(postition(write_ptr - position(read_ptr));
    else
        return sizeof(writebuff)                      //Startzustand, noch nichts geschrieben
    
    int position(char* zeiger){
        for(int i = 0; i<sizeof(writebuff); i++){
            if(&writebuff[i] == zeiger)              //Wenn Adressen gleich sind (falls das so machbar ist *g*)
                return i;
        }
    }
    

    @CStoll:
    Was macht denn die Zeile space = /überrundet?/ ? 0 : 1024; ????
    Vor allem das ? 0 : 1024 verwirrt mich 😉

    Herzlichen Dank



  • cyper schrieb:

    @CStoll:
    Was macht denn die Zeile space = /überrundet?/ ? 0 : 1024; ????
    Vor allem das ? 0 : 1024 verwirrt mich 😉

    Wenn die Zeiger identisch sind, gibt es zwei verschiedene Möglichkeiten: (a) der Lesezeiger hat den Schreibzeiger eingeholt - der Puffer ist leer, (b) der Schreibzeiger hat den Lesezeiger überrundet - der Puffer ist voll.

    (und zu der Konstruktion ?: such mal in deinem C++-Buch nach Konditional-Operator (oder kurz: das ist eine abkürzende Schreibweise für "if(überrundet) space=0; else space=1024;"))



  • Vielen Dank, ich denke das hilft mir schon einiges weiter.



  • hab ich selber mal an einem ringpuffer versucht. das kam raus: http://cracki.incast-security.de/pub/projects/beispiele/060131 C ringpuffer/ringbuf.c



  • c.rackwitz schrieb:

    hab ich selber mal an einem ringpuffer versucht. das kam raus: http://cracki.incast-security.de/pub/projects/beispiele/060131 C ringpuffer/ringbuf.c

    ich nehm immer das hier:

    #ifndef QUE_INCLUDED
    #define QUE_INCLUDED
    
    #include "standard_types.h"
    #include "features.h"
    
    ////////////////////////////////////////// QUEUE /////////////////////////////////////////
    
    /* Synchronization options */
    typedef enum
    {
       QS_NOSYNC,  /* Not synchronized */
       QS_SYNC     /* Synchronized */
    } QUE_SYNC;
    
    /*
       Code to be executed when synchronization is enabled
       Hardware/platform specific !!!
    */
    #define QUE_SYNC_ENTRY __asm sei
    #define QUE_SYNC_EXIT  __asm cli
    
    /* Layout of a QUE */
    typedef struct
    {
       volatile UINT16 readidx;     /* Read index */
       volatile UINT16 writeidx;    /* Write index */
       volatile UINT16 count;       /* Number of bytes actually queued */
       UINT16 size;            		/* Buffersize */
       QUE_SYNC sync;          		/* interrupt sync? */
       UINT8 PTR buffer;       		/* Data field */
    } QUE_T;
    
    /* Prototypes */
    extern UINT16 QUE_Write (QUE_T PTR f, UINT8 PTR data, UINT16 size);
    extern UINT16 QUE_Read (QUE_T PTR f, UINT8 PTR data, UINT16 size);
    extern void QUE_Initialize (QUE_T PTR q, UINT8 PTR mem, UINT16 size, QUE_SYNC sync);
    extern UINT16 QUE_Peek (QUE_T PTR f, UINT8 PTR data, UINT16 size);
    extern UINT16 QUE_Delete (QUE_T PTR f, UINT16 size);
    
    /* Informational macros */
    #define QUE_GetCount(__q__) ((__q__)->count)
    #define QUE_GetFree(__q__) ((__q__)->size-(__q__)->count)
    
    /* Macros that are too small to be a function */
    #define QUE_Purge(__q__) {(__q__)->count=0;(__q__)->readidx=0;(__q__)->writeidx=0;}
    
    #endif // QUE_INCLUDED
    
    #include "que.h"
    
    //////////////////////////////// QUEUE ///////////////////////////////////////////
    
    /*
       Enqueues some bytes
        -----------------
       IN:   f     - The queue object
              data  - Where the bytes are
              size  - Number of bytes which should be queued
        OUT:  Number of bytes actually enqueued
        INFO: The number of queued bytes may be smaller as requested
    */
    UINT16 QUE_Write (QUE_T PTR f, UINT8 PTR data, UINT16 size)
    {
       UINT16 s; /* Iterator */
    
       /* Queue full? */
       if (f->count == f->size)
          return 0;
    
       /* Do for all the bytes */
       for (s=0; s<size; s++)
       {
          /* Store that content */
          f->buffer[f->writeidx] = data[s];
          f->count++;
          f->writeidx++;
          /* Wrap around */
          if (f->writeidx == f->size)
             f->writeidx = 0;
          /* The queue is full now */
          if (f->count == f->size)
          {
          	 s++;
             break;
       	  }
       }
       /* Return number of bytes stored */
       return s;
    }
    
    /*
       Dequeues some bytes
        -------------------
       IN:   f     - The queue object
              data  - Where the bytes should be written
              size  - Number of bytes to transfer
        OUT:  Number of bytes actually dequeued
        INFO: The number of transferred bytes may be smaller than requested
    */
    UINT16 QUE_Read (QUE_T PTR f, UINT8 PTR data, UINT16 size)
    {
       UINT16 s;
    
       /* The queue is empty */
       if (f->count == 0)
          return 0;
    
       /* Possibly disable calling the write function */
       if (f->sync == QS_SYNC)
          QUE_SYNC_ENTRY;
    
       /* Try to dequeue all that stuff */
       for (s=0; s<size; s++)
       {
          /* Transfer */
          data[s] = f->buffer[f->readidx];
          f->count--;
          f->readidx++;
          /* Wrap around */
          if (f->readidx == f->size)
             f->readidx = 0;
          /* The queue is empty now */
          if (f->count == 0)
          {
          	 s++;
             break;
       	  }
       }
    
       /* Re-Enable calls to the write function */
       if (f->sync == QS_SYNC)
          QUE_SYNC_EXIT;
    
       /* Return number of bytes transferred */
       return s;
    }
    
    UINT16 QUE_Peek (QUE_T PTR f, UINT8 PTR data, UINT16 size)
    {
       UINT16 s;
       UINT16 count;
       UINT16 readidx;
    
       /* The queue is empty */
       if (f->count == 0)
          return 0;
    
       count = f->count;
       readidx = f->readidx;
    
       /* Try to dequeue all that stuff */
       for (s=0; s<size; s++)
       {
          /* Transfer */
          data[s] = f->buffer[readidx];
          count--;
          readidx++;
          /* Wrap around */
          if (readidx == f->size)
             readidx = 0;
          /* The queue is empty now */
          if (count == 0)
          {
          	 s++;
             break;
       	  }
       }
    
       /* Return number of bytes transferred */
       return s;
    }
    
    UINT16 QUE_Delete (QUE_T PTR f, UINT16 size)
    {
       UINT16 s;
    
       /* The queue is empty */
       if (f->count == 0)
          return 0;
    
       for (s=0; s<size; s++)
       {
          f->count--;
          f->readidx++;
          /* Wrap around */
          if (f->readidx == f->size)
             f->readidx = 0;
          /* The queue is empty now */
          if (f->count == 0)
          {
          	 s++;
             break;
       	  }
       }
    
       /* Return number of bytes transferred */
       return s;
    }
    
    /*
       Allocates a queue object
        ------------------------
       IN:   q     - The que object
            mem   - A pointer to memory for that queue
            size  - Size of memory (mem, see above)
             sync  - QS_SYNC == Disable interrupts on reads
    */
    void QUE_Initialize (QUE_T PTR q, UINT8 PTR mem, UINT16 size, QUE_SYNC sync)
    {
       q->sync = sync;
       q->size = size;
       q->buffer = mem;
       QUE_Purge (q);
    }
    

Anmelden zum Antworten