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 SpeicherHat 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 SpeicherHat 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 michHerzlichen Dank
-
cyper schrieb:
@CStoll:
Was macht denn die Zeile space = /überrundet?/ ? 0 : 1024; ????
Vor allem das ? 0 : 1024 verwirrt michWenn 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); }