在O(n)搜索中使用i + 1是安全的吗?

时间:2013-03-17 14:36:16

标签: c++ c

我问自己,使用i+1检查下一个号码是否与当前号码相同是否安全...示例:

int search(int el, int* a, int n) {

if(a == NULL && n<0)
{
    return NULL;
}

for(int i=0; i<n; i++)
{
    if((a[i] == el )&& (a[i+1] != el)) // here I check next element
    {
        return i; // if I find it, return a position.
    }
}

return -1; // else return -1
}

如果我们有一个长度为4的数组,那么a[i+1]将传递一个数组长度,但程序仍然有效。

5 个答案:

答案 0 :(得分:1)

不,访问超出范围的元素是未定义的行为

你的程序可能“似乎”可以工作,但是你不能指望任何东西。它可以在你的机器上工作,并在另一台机器上崩溃。或者它可以在现在的所有机器上运行,但不能在明天运行。在使用下标运算符之前,应检查索引是否超出范围。

您可以考虑更改周期,以便它永远不会访问越界元素:

for (int i = 0; i < n - 1; i++)
//                  ^^^^^

然后,作为特例,你必须分别处理数组中的最后一个元素。

答案 1 :(得分:0)

这是不正确的,当i到达其最后一个值(n-1)时,你检查一个不存在的元素的值(C标准允许你有一个指向一个接一个元素的指针,但不要取消引用它。)

您可以像这样修复代码:

 if((a[i] == el ) && ((i == n-1) || (a[i+1] != el)))

答案 2 :(得分:0)

如果n是数组中的最后一个元素,那么i + 1在这种情况下是安全的。如果n是数组中元素的数量,i + 1似乎在大多数时间都可以正常工作,但是安全的。

在这种情况下,您正在访问数组范围之外的元素,这可能会导致从错误的结果到崩溃程序。但是,大多数情况下它似乎都会起作用,这使得问题很难在调试时进行调试。

答案 3 :(得分:0)

我不清楚你在问什么。即使数组访问很昂贵,访问a[i]a[i+1]仍然具有O(N)复杂性。你无法做的是增加基于i的复杂性(例如从0到i的额外循环),或修改i(例如)根据某些条件减少它。)

正如其他人已经指出的那样,问题在于将最后一个元素与不存在的数据进行比较:要么出错,要么可能发生崩溃,或者程序出现到正在工作 - 实际上工作大多数 - 直到那个未知的,可能是随机的最后一个项目将触发比较,并产生意外结果的时间。

您应该检查数组大小是否至少为1(无论如何都应该是特殊情况,不能对单个元素进行比较!)然后仅循环到n-1。或者您可以将先前的值保存在临时变量中;取决于平台,这将是(可能更快)寄存器,或(可能更慢)堆栈位置。在大多数情况下,我只是说明我打算与下一个元素进行比较,就像你一样,让编译器对其进行排序。

答案 4 :(得分:0)

没有

int main(void)
{
    char pumpkin[8];
    int a[4];
    int i, p;

    a[0] = 3760;
    a[1] = 100001;
    a[2] = 595959;
    a[3] = 1886221680;

    pumpkin[0] = 'p';
    pumpkin[1] = 'u';
    pumpkin[2] = 'm';
    pumpkin[3] = 'p';

    for (i = 0; i < 4; i++) {
        p = search(a[i], a, 4);

        if (p >= 0)
            printf("Found it at position %d: %d.\n", p, a[i]);
        else
            printf("Value not found.\n");
    }


    return 0;
}

在我的机器上:

$ gcc -std=c11 -o boundserror boundserror.c
$ ./boundserror 
Found it at position 0: 3760.
Found it at position 1: 100001.
Found it at position 2: 595959.
Value not found.

发生什么事了?编译器在[3]中写入了值1886221680,如果存在,则编号为[4]。关于在您的机器上工作的程序:阅读有关我的机器概念的工作。

http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html