c中的全局计数器未按预期工作

c中的全局计数器未按预期工作,c,C,我有一些我正在处理的队列代码。我试图使用全局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 deque

我有一些我正在处理的队列代码。我试图使用全局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项

什么会导致这个问题

编辑#1:使代码示例与我实际编写的代码匹配

这不是线程

编辑#2:我是个白痴,应该这么做而不是假设。 我认为对enqueue()和dequeue()的调用是错误的


请注意,使用真实指标,而不是猜测。

最简单的解决方案是,如果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;
}
int size=0;
int溢出=0;
int-enqueue()
{
如果(尺寸<最大值)
大小++;
其他的
溢出++;
返回0;
}
int dequeue()
{
如果(溢出)
溢出--;
否则,如果(尺寸)
大小--;
返回0;
}

如果您不能使用调试器,我建议在两个函数中添加print语句,显示大小相等,然后在运行程序后检查输出。通常在查看打印日志时,问题非常明显。

您发布的代码没有明显的错误,因此这表明您剪切的代码或您调用代码的方式有问题。你必须自己调试这个。目前有两种主要的调试技术可以帮助您:

正如@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)满足您对
大小的任何更改的期望。

据我所知,我们还需要一些代码。(我希望我没有错过一些明显的东西:3)我发现自己担心缺乏对if块进行范围界定的
{}
。你能在工作代码中省去减量吗?把编译和演示你的问题的最小数量的代码贴出来。如果你删除了一些东西,问题就消失了,那么这部分显然与问题有关。编译你刚刚发布的代码。它是否遇到了您所问的问题?(答案是否定的——我编译了这段代码,它运行得很好)。问题仍然存在于您尚未发布的内容中。请检查
大小是否从未、从未、从未在除enqueue()或dequeue()之外的任何位置递增/递减。例如,您可能超过了最大值。这就是全局变量的问题。