受到this topic的启发,我决定编写一个简单的程序来实现这一点。
逻辑并不复杂,我75%的时间都有一个工作程序请求数的数量定义为#define BUFSIZE x
,其中x
可以是任意整数。
问题出现在((BUFSIZE+1) % sizeof(int)) == 0
时。
例如,如果BUFSIZE=10
,当BUFSIZE=11
出现异常行为时,我的程序将正确运行。
这是源代码:
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 7
int max(int *buf);
int main()
{
int bufsize = BUFSIZE, *buf = malloc(sizeof(int[bufsize]));
// read values
int *ptr = buf;
while(--bufsize + 1)
{
printf("Input %d: ", BUFSIZE - bufsize);
scanf("%d", ptr);
++ptr;
}
// reset pointer and determine max
ptr = buf;
printf("\nMax: %d\n", max(ptr));
// cleanup
free(buf);
ptr = NULL;
buf = NULL;
exit(EXIT_SUCCESS);
}
int max(int *buf)
{
int max = 0;
while(*buf)
{
printf("%d\n", *buf);
if(*buf > max) max = *buf;
++buf;
}
return max;
}
一些BUFSIZE=2(正确)和BUFSIZE=3(错误)的示例输出。
suze:/home/born05/htdocs/experiments/c# gcc input.c && ./a.out
Input 1: 12
Input 2: 23
12
23
Max: 23
suze:/home/born05/htdocs/experiments/c# gcc input.c && ./a.out
Input 1: 12
Input 2: 23
Input 3: 34
12
23
34
135153
Max: 135153
我觉得这是一件非常合乎逻辑的事情,但我不能确切地指出造成这种不良行为的原因有人能给我指出(也许是显而易见的)缺点吗?
最佳答案
这甚至对任何BUFSIZE
的值都有效,这实际上是纯粹的运气(事实上,对我来说,它在BUFSIZE=2
上断开)这就是原因——这:
while(*buf)
不是检查缓冲区结尾的适当方法。这样做的目的是加载
buf
指向的地址的值,并查看内容是否为零因为您从未在缓冲区的末尾显式地放置过零,所以这不一定是真的,而且该循环可能永远运行,读入超过buf
数组末尾的内存并调用未定义的行为。您需要在
buf
数组的末尾分配一个额外的元素并将其设置为零(但是如果用户输入0
作为输入,那么您的程序将无法正常工作),或者显式地将buf
的大小传递给max
函数并使用它来确定何时应该停止循环。关于c - 程序有25%的时间不当行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3334539/