-7

gnu 编译器,从命令行运行,使用没有 mods 的 sublime text 2。

显示递归函数的运行时间的简单程序,该函数采用 5000 索引数组,随机数在 0 和 1 之间均匀分布,并将它们相加(这意味着您应该在 2500 的球场某处得到一个值)。下面的代码始终可以正常工作,并产生相当接近预期值的东西。但是,在其中一个 couts 中添加一个新行/选项卡,一切都会在手提篮中陷入困境(见下文)。

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

double sumOfRandomNumbers(double arrayToFill[], int lengthOfArray){
    if(lengthOfArray == 0) return arrayToFill[lengthOfArray];
    return arrayToFill[lengthOfArray] + sumOfRandomNumbers(arrayToFill, lengthOfArray - 1);
}

double seconds(){return double(clock())/CLOCKS_PER_SEC;}

int main(){

    int sizeOfArray = 5000;
    double sum = 0.0, deltaT = 0.0, array[sizeOfArray];
    srand(time(NULL));

    for(int i = 0; i < sizeOfArray; i++) array[i] = double(rand())/double(RAND_MAX);

    cout << "\nRecursive Method\n";
    deltaT = seconds();
    for (int i = 0; i < 100000; i++){
        sum = sumOfRandomNumbers(array, sizeOfArray);
        if (i%10000 == 0) cout << i/1000 << " percent complete\n";
    }
    deltaT = seconds() - deltaT;
    cout << "\n\n\t\tRecursive method found sum to be " << sum;
    cout << "\n\t\tThis recursive calc took " << deltaT << " seconds to run.\n";

}

输出

Recursive Method
0 percent complete
10 percent complete
20 percent complete
30 percent complete
40 percent complete
50 percent complete
60 percent complete
70 percent complete
80 percent complete
90 percent complete


                Recursive method found sum to be 2466.4
                This recursive calc took 12.226 seconds to run.

这是更新后的代码,其中的更新与编译时完全相同。请注意奇怪的输出。我已将添加的代码加粗。如果它没有出现或很难看到,这就是变化

if (i%10000 == 0) cout << i/1000 << " percent complete\n";

if (i%10000 == 0) cout << "\n\t" << i/1000 << " percent complete\n";

..................................................... …………………………………………………………………………………………………………

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

double sumOfRandomNumbers(double arrayToFill[], int lengthOfArray){
    if(lengthOfArray == 0) return arrayToFill[lengthOfArray];
    return arrayToFill[lengthOfArray] + sumOfRandomNumbers(arrayToFill, lengthOfArray - 1);
}

double seconds(){return double(clock())/CLOCKS_PER_SEC;}

int main(){

    int sizeOfArray = 5000;
    double sum = 0.0, deltaT = 0.0, array[sizeOfArray];
    srand(time(NULL));

    for(int i = 0; i < sizeOfArray; i++) array[i] = double(rand())/double(RAND_MAX);

    cout << "\nRecursive Method\n";
    deltaT = seconds();
    for (int i = 0; i < 100000; i++){
        sum = sumOfRandomNumbers(array, sizeOfArray);
        if (i%10000 == 0) cout << "\n\t" << i/1000 << " percent complete\n";
    }
    deltaT = seconds() - deltaT;
    cout << "\n\n\t\tRecursive method found sum to be " << sum;
    cout << "\n\t\tThis recursive calc took " << deltaT << " seconds to run.\n";

}

输出

Recursive Method

        0 percent complete

        10 percent complete

        20 percent complete

        30 percent complete

        40 percent complete

        50 percent complete

        60 percent complete

        70 percent complete

        80 percent complete

        90 percent complete


                Recursive method found sum to be 1.15021e+257
                This recursive calc took 12.262 seconds to run.

注意我们是如何从一个非常合理的 2466.4 变成一个完全荒谬的 1.15 x 10^257。没有进行其他更改,即使经过数十次运行,这些数字也非常典型,您在上面看到的代码就是编译和运行的确切代码。

4

2 回答 2

3

您在此处拥有越界访问权限:

double sumOfRandomNumbers(double arrayToFill[], int lengthOfArray){
    if (lengthOfArray == 0) return arrayToFill[lengthOfArray];
    //                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    return arrayToFill[lengthOfArray] + 
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^
           sumOfRandomNumbers(arrayToFill, lengthOfArray - 1);
}

这会在您的程序中注入未定义的行为。当你的程序有未定义的行为时,一切都可能发生,包括有时程序似乎运行得很好

于 2013-03-08T23:25:34.283 回答
0

您正在阅读 void memory ( arrayToFill[lengthOfArray])。这是未定义的行为,所以它会变得很糟糕。也许你碰巧碰到了控制台的内存,谁知道呢。无论确切原因是什么,这都不是编译器中的错误。这是您的代码中的错误。

更新:

为了提供更多详细信息,因为array是堆栈中的最后一项,所以当应用程序启动时,超出它的内存通常不会被使用并且初始化为零(操作系统为安全而做的事情;确保您无法读取任何可能的旧密码例如,已被另一个程序留下)。

但是,如果调用另一个具有局部变量的函数,它将在该空间中放置一个值(不会被清除;您永远不应该访问它,并且操作系统不在乎您是否阅读自己的密码)。

可能是 cout 的<<运算符有一些内部条件,有时将它的第一个局部变量设置为非零值。也许第一个变量是bool beganWithNewline(人为的!),它将您读取的元素的第一个字节1设置为分数部分,但你明白了)。

于 2013-03-08T23:27:14.563 回答