2009-07-06 21 views
0

編集:キューが2dの理由は、cmdがNULLに等しいようにCommandのポインタが必要なためです。 NULL ==(void *)。これは私が混乱するところで、なぜ私がここに来たのかです。 :)ポインタの混乱へのポインタ

私がPythonで持っている別の問題を試してみるために、私はCで小さなテストプログラムを実装しています。少しは分かりますが、明らかに私は混乱しています。私は、非同期USB転送で使用される単純なキューを作成しようとしています。待ち行列からポップされたすべてのコマンドが同じであるため、何かが待ち行列で正しくない。代わりにキュー[1024] [0]をキュー[1024] [1]として書き込むと、コマンドは2つの異なるコマンドを交互に実行し、command_thread_mainでプログラムがクラッシュします。どうやら、cmdがNULLでなければならないことに気付かないでしょう。 [1]を上げると、それ以上は効果がありません。何かヒント?

typedef struct Command { 
    void (*cb) (char *data, int size); 
    unsigned char *data; 
    int size; 
} Command; 

struct Command queue[1024][0]; 

int queueEnd = 0; 
int queueStart = 0; 

static void queue_push(void (*cb), unsigned char *data, int size) { 
    if (queueEnd >= 1024) 
     return; 
    queue[queueEnd]->cb = cb; 
    queue[queueEnd]->data = data; 
    queue[queueEnd]->size = size; 
    queueEnd++; 
} 

struct Command * queue_pop(void) { 
    if(queueStart > queueEnd) 
     return NULL; 
    return queue[queueStart++]; 
} 

static void *command_thread_main(void *arg) { 
    struct Command *cmd; 
    while (!do_exit) { 
     if(locked) continue; 
     locked = 1; 
     cmd = queue_pop(); 
     if(cmd != NULL) 
      cmd->cb(cmd->data, cmd->size); 
    } 
} 
+2

なぜアレイは2Dですか?それは間違って見える – Hasturkun

答えて

2
  • :あなたは、としてそれを宣言する必要がありますか?つまり、[0]または[1]などではありません。
  • queue_popqueueStart >= queueEndをテストする必要があります。
  • 円形配列を実装する必要があります。

今は、構造体自体をポインタではなく配列に格納します。それは賢明です。あなたはしかし.->を変更する必要があります:

queue[queueEnd].cb = cb; 
queue[queueEnd].data = data; 
queue[queueEnd].size = size; 

(ひいてはqueue_popはタイプstruct Command(ないstruct Command *)の変数を返す必要があり、そしてメインコードもそれに応じて更新する必要があります。)

のうちもちろんでもポインタを渡しますが、このような小さな構造体/キューでは実際の必要はありません。

+0

に変更してください。1)ポインタが必要です。 2)queueStartがqueueEndを通過すると、キューは空であるとみなされます。 queueStart == queueEndの場合、queueには少なくとも1つのメンバーが出現します。 3)このキューは一度使用され、たいていは65のコマンドがそれを通過します。 Pythonで問題をデバッグするのに役立つ誰かを満足させる簡単なテストプログラムです。循環アレイは必要ありません! – Scott

+0

最初は 'queueStart = queueEnd = 0'なので、' queueStart> queueEnd'はfalseですが、キューは実際には空です。あなたのコードは決して最後のコマンドをポップしません。 – Stephan202

+0

もう少し意味があります。 :) – Scott

3

私はあなたが他に何かを修正する必要があると思います。コマンドの2D配列があり、それらの次元の1つを0に設定しました!

キューにアクセスすると、1D構造として扱われているようです。あなたがstruct Command queue[1024];を意味するものではありません。

struct Command queue[1024]; 
+0

さて、私はキューから== NULLできるように、キューからポインタが必要です。 – Scott

+1

queue_popに '&queue [queueStart ++]'を返すか、配列をCommand * – Hasturkun

1

もう1つの問題は、structの配列としてキューを宣言しましたが、メンバーシップ.の代わりに逆参照->演算子を使用して、構造体へのポインタの配列として使用していることです。

私はsnarkyを発音するわけではありませんが、コンパイラの警告フラグ(-Wall for gcc)はお友達です。

+0

1)これが私がここにいる理由です。私は何か間違っているのは明らかですが、それが何であるかはわかりませんでした。私はこれを違う方法で提案しますか? 2)ああ、私はCの新人で、Cをコンパイルしています。コンパイラのヒントに感謝します。 – Scott

+0

これはシンプルなプログラムなので、キューはグローバル変数であり、キューの空き領域は再利用されません。ポップされた値にインデックスを戻すようにします。キューが空の場合は-1を返します。 また、適切なmutexを使用する必要があります。 –

+0

まあ、ミューテックスは絶対に必要ありません。キューは、スレッドが開始される前に満たされます。私が言ったように、それは非常に単純なプログラムです。私は、command_thread_mainが消費する約65のUSB転送を保持するキューを必要としました。 – Scott

2

他の人が指摘しているように、その2Dキューは間違いなく間違っています。あなたは1Dキューを必要とし、私が何をしたいことはポインタの配列であることを疑う:

Command * queue[1024]; 

私はいくつかの図を描き、あなたが道を行くと、問題について少し考えてreommendして、明確なコードで戻ってきます質問。

関連する問題