2017-10-19 30 views
0

我想知道为什么我无法显式更改时,我的代码为y [0]提供了更改的值。我已经提供在下面的链接的输出:未定义的行为:数组元素的值隐式/不合逻辑地更改

Code Output

代码:

#include <iostream> 

int main() { 
    std::cout << "Enter total number of values of x/y" << std::endl; 
    int n; 
    std::cin >> n; 

    double x[n]; 
    double y[n]; 
    double df[n - 1][n - 1]; 

    std::cout << "Enter values of x:" << std::endl; 

    for (int i = 0; i < n; i++) { 
     std::cin >> x[i]; 
    } 

    std::cout << "Enter values of y:" << std::endl; 

    for (int i = 0; i < n; i++) { 
     std::cin >> y[i]; 
    } 

    std::cout << std::endl; 

    for (int i = 0; i < n; i++) { 
     df[i][0] = y[i + 1] - y[i]; 
    } 

    std::cout << "value of y[0] before: " << y[0] << std::endl; 

    for (int j = 1; j < n - 1; j++) { 
     for (int i = 0; i < n; i++) { 
      df[i][j] = df[i + 1][j - 1] - df[i][j - 1]; 
     } 
    } 

    std::cout << "value of y[0] after: " << y[0] << std::endl; 
} 

此外,它给Y的一个不变的值[0],如果我使用动态分配内存:

double* x = new double[n]; 
double* y = new double[n]; 

我提到了这个链接:Value of array member changes illogically,但我无法获得有关如何是一个明确的答案它发生,因为它不提供任何代码(如评论中所述)。

我想知道为什么这发生在我的代码与静态数组,而不是动态分配的?

+2

在'df'赋值循环的最后一次迭代中,您有'i == n - 1'。这意味着你正在访问数组末尾的'df [n-1] [0]'。访问该元素是未定义的行为,可能会解释您遇到的任何问题。 –

+2

'double x [n];'不是标准的C++,你在用什么编译器? – user463035818

+1

更糟的是,当'i == n - 1'时,最后一个循环访问'df [n]',这是两个超出边界的元素。 – chris

回答

1

您正在阅读的出界多次援引因而其undefined behavior可能导致修改y[0]值。

double df[n - 1][n - 1]; 

,但与下面的语句和表达式您正在访问数组元素越界:

df[i][0] = y[i + 1] - y[i]; // everything except the y[i] 
df[i + 1][j - 1] 
df[i][j] 
df[i][j - 1]; 
df[i + 1][j - 1] 
df[i][0] = y[i + 1] - y[i] 
df[i][j] = df[i + 1][j - 1] - df[i][j - 1]; // everything 

要么修改数组边界为大于n-1或确保您定义的数组边界索引是小于n-1n在适当情况下可以避免未定义的行为。这就是说,可变长度数组不是C++标准的一部分。

+0

如果变长数组不是它的一部分,标准gcc编译器不应该停止编译这些代码吗? –

+0

@KewalShah有些编译器支持它,使用适当的标志时会发出警告。 – Ron

+0

@KewalShah大多数编译器都支持各种扩展。一些扩展是隐式的(你需要一个标志或选项来禁用它),而其他扩展是明确的(你需要一个标志或选项来启用它)。 gcc的VLA支持是一种隐含的主动扩展(如果你问我的话,这样做的确会有很大的好处)。 –