глобальный счетчик в с не работает, как ожидалось - PullRequest
2 голосов
/ 21 августа 2009

У меня есть немного кода очереди, над которым я работал. Я пытался использовать глобальный int для отслеживания размера очереди.

#define MAX 100

int size=0;
int gEnqueue=gDequeue=0;

int enqueue()
{
     gEnqueue++;
     if( size == MAX )
         return QUEUE_FULL;
/* snip the actual queue handling */
     size++;
     return 0;
}

int dequeue()
{
     gDequeue++;
     if(!size)
         return QUEUE_EMPTY;

/* snip actual queue handling */
     if(size)
         size--;
     return 0;
}

конечно, кода гораздо больше, но слишком много, чтобы публиковать.

То, что происходит - размер застревает на максимуме, который я установил. Обе функции вызываются четное количество раз. Если я выбрасываю очередь, я вижу, что в ней всего 3 элемента.

Что может вызвать эту проблему?

edit # 1: пример кода соответствует тому, что я на самом деле кодировал

Это не с резьбой.

edit # 2: я идиот и должен был сделать это вместо того, чтобы предполагать. Я был не прав насчет того, что вызовы были даже в enqueue () и dequeue ().

Заметьте, используйте реальные метрики, а не догадки.

Ответы [ 3 ]

2 голосов
/ 21 августа 2009

Если вы не можете использовать отладчик, я бы предложил добавить операторы печати в обе функции, показывающие, какой размер равен, а затем после запуска программы проверить вывод. Обычно при просмотре журнала печати проблема довольно очевидна.

0 голосов
/ 21 августа 2009

Нет ничего явно неправильного в коде, который вы разместили, поэтому это говорит о том, что что-то не так с кодом, который вы взяли, или в способе, которым вы вызываете код. Вам придется отладить это для себя. На этом этапе вам помогут две основные техники отладки:

Как и @KPexEA, отладка с использованием printf () или других операторов ведения журнала. Поместите printf () в начало и конец обеих функций, распечатывая столько состояний, сколько, по вашему мнению, может быть полезным.

int enqueue()
{
     printf("enqueue(): Enter: size=%d\n", size);
     if( size == MAX ) {
         printf("enqueue(): Exit: QUEUE_FULL\n");
         return QUEUE_FULL;
     }
     /* snip the actual queue handling */
     size++;
     printf("enqueue(): Exit: size=%d\n", size);
     return 0;
}

int dequeue()
{
     printf("dequeue(): Enter: size=%d\n", size);
     if(!size) {
     printf("dequeue(): QUEUE_EMPTY\n");
         return QUEUE_EMPTY;
     }

     /* snip actual queue handling */
     if(size)
         size--;
     printf("dequeue(): Exit: size=%d\n", size);
     return 0;
}

Изучив выходные данные, должно стать очевидным, что происходит с размером вашей очереди. (Вы также можете подсчитать фактическое количество элементов в своей очереди и распечатать его при входе и выходе из своих функций.)

Другая техника - интерактивная отладка. Это особенно полезно, чтобы точно определить, как работает ваш код, но вы должны сидеть там каждый раз, когда запускаете программу, чтобы посмотреть, как она работает. (Если ваша ошибка возникает каждый раз, это легко; если она возникает время от времени, трудно вернуться назад и воссоздать поток вашей программы после факта.) Установите точку останова в начале каждой из ваших функций и используйте отладчик для отображения значения size. Установите другую точку останова в конце каждой функции и убедитесь, что (1) точка останова действительно получена, и (2) ваши ожидания относительно любых изменений, внесенных в size, удовлетворены.

0 голосов
/ 21 августа 2009

Самое простое решение - не вызывать "enqueue", если size == MAX.

Но если это невозможно, попробуйте это:

int size=0;
int overflow=0;

int enqueue()
{
     if( size < MAX )
         size++;
     else
         overflow++;
     return 0;
}

int dequeue()
{
     if(overflow)
         overflow--;
     else if(size)
         size--;
     return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...