2016-10-25 3 views
1

私はリングバッファのコードを以下に書いています。私は位置指示器なしでポインタだけを使いたいと思っていました。しかし、私は執筆中に期待される結果を得ていません。書き込みは行われますが、1回目の入力後に停止しません。それはさらに続く。読み取り操作が正しいようです。 デバッガを使ってデバッグしようとしました。しかし、驚いたことに、if(head>(myRing+AVAILABLE_SIZE*sizeof(myRing[0])))はwriteToRing()関数で実行されていません。デバッガはこの手順をスキップします。また、最初の++ ++はこの関数で実行されません。代わりに、コードは最初にif(head == tail)に行き、その後++に戻ります。理由を見つけることができません。 私はMinGWの直接ポインタ操作を使用したリングバッファの実装に関する問題

#define MAX_SIZE 2 
#define AVAILABLE_SIZE (MAX_SIZE-1) 

/* 
Program to construct and access ring buffer without structure. 
This program makes use of pointer. Even without pointer it is possible to manage 
*/ 

int myRing[MAX_SIZE]; 
int *head=myRing; // Initialize next element than tail 
int *tail=myRing; 

enum ERROR_LIST 
{ 
    SUCCESS=0, 
    BUFFER_FULL=-1, 
    BUFFER_EMPTY=-2 
    }; 

int writeToRing(int data) 
{ 
    head++; 
    if(head>(myRing+AVAILABLE_SIZE*sizeof(myRing[0]))) 
    { 
     head=myRing; //wraps over 
    } 
    else 
    { 
     // Do nothing 
    } 
    if(head==tail) 
    { 
     head--; 
     if(head<myRing)  // In case head is less than starting address. assign max address 
     { 
      head=(myRing+AVAILABLE_SIZE*sizeof(myRing[0])); 
     } 
     printf("Buffer full\n"); 
     return(BUFFER_FULL); 
    } 
    else 
    { 
     *head=data; 
    } 
    return(SUCCESS); 
} 

int readFromBuffer(int* data) 
{ 
    if(tail==head) 
    { 
     return(BUFFER_EMPTY); 
    } 
    else 
    { 
     tail++; 
     if(tail>(myRing+AVAILABLE_SIZE*sizeof(myRing[0]))) 
     { 
      tail=myRing; 
     } 
     *data=*tail; 
     return(SUCCESS); 
    } 
} 

int main() 
{ 
    int option; 
    int data; 
    while(1) 
    { 
    printf("Enter Your option. 1 for writing to buffer, 2 for reading from Buffer\n"); 
    scanf("%d",&option); 
    if(option==1) 
    { 
     printf("Enter the data to be written\n"); 
     scanf("%d",&data); 
     if(writeToRing(data)) 
     { 
      printf("Buffer is Full. Remove the contents first\n"); 
     } 
    } 
    else if(option==2) 
    { 
     if(!readFromBuffer(&data)) 
     { 
      printf("The data read = %d\n",data); 
     } 
     else 
     { 
      printf("Buffer is Empty\n"); 
     } 
    } 
    else 
    { 
     printf("Invalid Option\n"); 
    } 

    } 
    return(0); 
} 

編集でコード::ブロックを使用しています: は別のアプローチでコードを更新しました。このコードでは、1データバイトが無駄にならない。私はテストして働いているようだ。しかし、他の問題がある場合は、私に知らせてください。タイプ指定子%uのscanfには2つの警告があり、修正方法を確認する必要があります。私は基本的にこの場合バイトを読みたいと思う。私が整数読み取りのために行くなら、問題はありません。

#include <stdio.h> 
#include <stdint.h> 
#define MAX_SIZE 3 

uint8_t BUFFER_FULL=0; // Initially buffer full flag is cleared 
uint8_t BUFFER_EMPTY=1; // Initially buffer empty flag is set 

/* 
Program to construct and access ring buffer without pointer. 
Also this makes use of full buffer and checks for buffer empty or buffer full condition 
before calling write or read functionality, 
*/ 

uint8_t myRing[MAX_SIZE]; 
uint8_t head=0; // Initialize the head 
uint8_t tail=0; // Initialize the tail 
uint8_t maxPosition= MAX_SIZE-1; 


void writeToRing(uint8_t data) 
{ 
    head=head+1; 
    if(head>maxPosition) 
    { 
     head=0; 
    } 
    else 
    { 
     // Do nothing 
    } 
    // Write the data to buffer 
    myRing[head]=data; 
    BUFFER_EMPTY=0; // Indicate that buffer is not empty 

    if(head==tail) 
    { 
     printf("Buffer full No further data can be written\n"); 
     BUFFER_FULL=1; 
    } 
} 

void readFromRing(uint8_t* data) 
{ 
    // Initially buffer is empty (BUFFER_EMPTY=1). At that point, calling portion cannot call this function. 
    // Later when data is written, writeToRing() function will clear BUFFER_EMPTY flag. 

    tail++; 
    if(tail>maxPosition) 
    { 
     tail=0; 
    } 
    *data=myRing[tail]; 
    // Once reading is done, ensure that BUFFER_FULL flag is cleared. 
    BUFFER_FULL=0; 
    if(tail==head) 
    { 
     printf("Buffer is now Empty. No further reading possible\n"); 
     BUFFER_EMPTY=1; 
    } 
} 

int main() 
{ 
    uint8_t option; 
    uint8_t data; 
    while(1) 
    { 
     printf("Enter Your option. 1 for writing to buffer, 2 for reading from Buffer\n"); 
     scanf("%u",&option); 
     if(option==1) 
     { 
      if(!BUFFER_FULL) 
      { 
       printf("Enter the data to be written\n"); 
       scanf("%u",&data); 
       writeToRing(data); 
      } 
      else 
      { 
       // Nothing to be done in case buffer is FULL 
       printf("Buffer should be cleared first\n"); 
      } 
     } 
     else if(option==2) 
     { 
      if(!BUFFER_EMPTY) 
      { 
       uint8_t data; 
       readFromRing(&data); 
       printf("The data read = %d\n",data); 
      } 
      else 
      { 
       printf("Buffer is Empty. Write something before you read\n"); 
      } 
     } 
     else 
     { 
      printf("Invalid Option\n"); 
     } 
    } 
    return(0); 
} 

答えて

2

正しい形式は次のようになります

if(head>(myRing+AVAILABLE_SIZE)) 
{ 
... 
} 

myRingがポインタであるので、「+」演算子は、それ自体で、素子サイズによって乗算を行います。

+0

実際、sizeof(int)を乗算せずに最初に試してみました。それは私を悩ませていました、そして、私はテスト目的のために変更し、削除するのを忘れました。デバッガが私が指示したようにステップをスキップしていた理由はわかりません。しかし今日、私はあなたの提案に従って行い、それは働いています。どこか愚かな間違いをしているにちがいありません。 – Rajesh

1

あなたはそれがリングバッファの終わりを示すコード

  1. 別のポインタ(wrap)を追加を簡素化します作ることができるカップルの改善点があります。 headtailwrapに等しい場合は、バッファの先頭に戻す必要があります。

  2. writeToRing関数では、一時ポインタ(temp)を使用してバッファがいっぱいかどうかを確認します。そうすれば、書き込みが成功するまではheadは影響を受けませんので、計算を元に戻す必要はありません。デバッガが変な行動していた理由については


int myRing[MAX_SIZE]; 
int *head = myRing; 
int *tail = myRing; 
int *wrap = &myRing[MAX_SIZE]; 

int writeToRing(int data) 
{ 
    int *temp = head+1; 

    if (temp == wrap) 
     temp = myRing; 

    if (temp == tail) 
     return BUFFER_FULL; 

    head = temp; 
    *head = data; 
    return SUCCESS; 
} 

int readFromRing(int *data) 
{ 
    if (tail == head) 
     return BUFFER_EMPTY; 

    tail++; 
    if (tail == wrap) 
     tail = myRing; 

    *data = *tail; 
    return SUCCESS; 
} 

、デバッグしているときに最適化がオフになっていることを確認してください。デバッガは、最適化されたコードに従うのに苦労します。

+0

これは埋め込みコード用で、オーバーフローが起こりそうもないので、私はtempを追加しませんでした。オーバーフローする機会がないと考えて、私は頭を元に戻すことができないかもしれないと思って余分なコピーと余分なメモリを避けることができました。デバッグにも来る:最適化を削除しても運がない。私はEclipseに行って、この問題が解決するかどうかを確認する必要があります(デバッグに特に必要な他のコンパイラ設定はわかりません) – Rajesh

関連する問題