You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++浮点运算代码出现异常值,请求排查与修复方案

C++数组越界导致的异常值问题修复

问题代码

#include <iostream>
#include <cmath>

int main() {

    int a,b,n;
    std::cin >> a >> b >> n;
    double xi[n];
    double yi[n];
    double h = (b - a + 0.0) / n + 0.0;
    
    for (int i = 0; i <= n; ++i) { //filling the arrays
        xi[i] = a + (h*i);
        yi[i] = xi[i]*xi[i]*std::acos(0.9*xi[i]);
    }
    for (int i = 0; i <= 5; ++i)  { //displaying first 5 elements of the arrays
        std::cout << "x" << i << ": " << xi[i] << "\n";
        std::cout << "y" << i << ": " << yi[i] << "\n\n";
    }
    return 0;
}

问题现象

输入a=0、b=1、n=10(或10的倍数)时,x0本该为0,实际显示0.451027;尝试强制给xi[0]赋值a后,x0仍为错误值,y0变成9.2684e-315,每次运行都出现该问题。

问题根源

你定义的xi[n]和yi[n]是长度为n的数组,合法下标范围是0到n-1。但填充数组的循环条件是i <= n,当i=n时,xi[n]和yi[n]已经超出数组合法下标范围,属于数组越界访问。

数组越界会破坏栈上的其他数据(比如循环变量i、数组的起始地址标记等),导致后续读取xi[0]时拿到被破坏后的垃圾值,强制赋值也因为栈数据被篡改而无法生效。

修复方案

方案1:调整数组长度

把数组定义改为double xi[n+1];和double yi[n+1];,因为你需要存储0到n共n+1个元素,刚好匹配循环的范围。

方案2:调整循环范围

如果不想修改数组长度,把填充循环的条件改为i < n,但这样会少存储x=b对应的元素,需根据实际需求选择。

修复后代码示例(方案1)

#include <iostream>
#include <cmath>

int main() {

    int a,b,n;
    std::cin >> a >> b >> n;
    double xi[n+1]; // 调整为n+1长度,适配0~n的下标
    double yi[n+1];
    double h = (b - a) / static_cast<double>(n); // 显式转换为浮点数除法,省略冗余的+0.0
    
    for (int i = 0; i <= n; ++i) {
        xi[i] = a + h * i;
        yi[i] = xi[i] * xi[i] * std::acos(0.9 * xi[i]);
    }
    for (int i = 0; i <= 5; ++i)  {
        std::cout << "x" << i << ": " << xi[i] << "\n";
        std::cout << "y" << i << ": " << yi[i] << "\n\n";
    }
    return 0;
}

额外说明

C标准中不支持变长数组(VLA)(即double xi[n];这种用运行时变量定义长度的数组),这是部分编译器(如GCC)的扩展特性。如果要编写标准C代码,建议用std::vector替代:

#include <vector>
// ...
std::vector<double> xi(n+1);
std::vector<double> yi(n+1);

内容的提问来源于stack exchange,提问作者h-swell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:13:17