2010-07-26 65 views
1

this topic的启发,我决定编写一个简单的程序。
逻辑并不复杂,我有一个工作程序75%的时间..被询问的数量被定义为#define BUFSIZE x,其中x可以是一个任意的int。
问题出现在((BUFSIZE+1) % sizeof(int)) == 0程序行为不当25%的时间

因此,例如,如果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 

我有感觉这是非常合乎逻辑的事情,但我不能把我的手指放在这种不正当行为的确切原因。有人能指出我的这个(也许是明显的)缺陷吗?

+0

呃?你在'buf [3]'和'buf [4]'分别使用了一个标记值,但你的大小分别是2和3。 – falstro 2010-07-26 12:00:05

回答

5

这实际上是纯粹的运气,这甚至适用于BUFSIZE的任何值。 (实际上,对我来说,它打破了BUFSIZE=2)。这是为什么 - 这:

while(*buf) 

是不是一个适当的方式来检查缓冲区的结束。它所做的是加载buf指向的地址处的值,并查看内容是否为零。由于你从不明确地将零置于缓冲区的末尾,所以这不一定是真的,并且该循环可能会永久运行,读入超过数组末尾的内存并调用未定义的行为。

你要么需要在buf数组的末尾分配额外的元素,并将其设置为零(但随后如果用户输入0输入你的程序将无法正常工作),或显式传递的buf大小到max函数并使用它来确定何时应该停止循环。

+0

所以,我迭代我的数组的方式是不正确的。什么是适当的方式来做到这一点?真的有必要将一个长度传递给'max()'? – 2010-07-26 12:07:44

+0

是的,我编辑了它。最好的方法是将buf长度传递给max,然后运行一个for(int i = 0; i 2010-07-26 12:09:04

+0

好吧,我改变了max()的原型,现在就像是一个魅力。很难习惯这些东西的明确性(当来自PHP世界时)。 – 2010-07-26 12:14:51

2

int bufsize = BUFSIZE, *buf = malloc(sizeof(int[bufsize])); 

应该

int bufsize = BUFSIZE, *buf = malloc(sizeof(int[BUFSIZE + 1])); 
buf[BUFSIZE] = 0; 

在你现在的代码,你的一个整数(sizeof(int[bufsize])评估为sizeof(int*))分配内存,而不是你需要BUFSIZE整数,包含一个额外的整数内存之后为null。

在您当前的代码中,您有所谓的未定义行为 - 您使用的内存不合法分配给您。在你的情况下,它有时有时不工作。那么,至少你现在知道它,而不是当它推动控制一个核电站。

1

你正在对待buf就好像它是一个以null结尾的字符串数组。你可能这样做,如果你的数据值保证永远不会是零,你实际上把零(你的程序没有做)。

而是试着改变你的MAX()函数是这样的(调整原型,并相应地调用位置):

int max(int *buf, int count) 
{ 
    int max = 0; 

    // Check inputs 
    if (buf == NULL || count <= 0) 
    { 
     printf("max(): bad parameter(s)\n"); 
     return 0; 
    } 

    while(count--) 
    { 
     printf("%d\n", *buf); 
     if(*buf > max) max = *buf; 
     ++buf; 
    } 
    return max; 
} 
+0

谢谢,我真的需要在我的系统中检查我的输入! – 2010-07-26 12:15:53

相关问题