受到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/

10-11 22:55