代码使用向量成功运行,但使用数组显示错误

Posted

技术标签:

【中文标题】代码使用向量成功运行,但使用数组显示错误【英文标题】:Code running successfully using vector but showing error using array 【发布时间】:2020-10-23 01:18:51 【问题描述】:

我正在练习一个数组操作问题。解决时我声明了一个数组(代码中的数组 A)。 对于某些测试用例,我遇到了分段错误。我用向量替换了数组并得到了交流电。我不知道这是什么原因。请解释一下。

#include <bits/stdc++.h>

using namespace std;

int main()

    int n,m,a,b,k;
    cin>>n>>m;
    vector<long int> A(n+2);
    //long int A[n+2]=0;

    for(int i=0;i<m;i++)
    
        cin>>a>>b>>k;
        A[a]+=k;
        A[b+1]-=k;
    
    long res=0;
    for(int i=1;i<n+2;i++)
    
        A[i]+=A[i-1];
        if(res<A[i])
        res=A[i];
    
    cout<<res;
    return 0;

【问题讨论】:

这是什么语言?请添加到标签。 您能否确保您提供的代码可以编译?这个例子没有。如果您对用于 n、m、a、b 和 k 的值进行硬编码,也会更有帮助。有很多方法可以在几个不同的地方按原样破坏代码,在您的情况下,无法判断它是如何或在哪里破坏的。 【参考方案1】:

由于您似乎很久没有使用 C++ 编程了,我将尝试对其进行分解,以便您更容易理解: 首先,c++ 不会为您初始化任何值,这不是 Java,所以请不要这样做:

int n,m,a,b,k;

然后使用:

A[a]+=k;
A[b+1]-=k;

在这一点上,我们不知道 a 和 b 是什么,据我们所知,它可能是 -300,你从未初始化它。因此,有时你很幸运,编译器初始化的数字不会导致分段错误,而其他时候你就没有那么幸运了,编译器初始化的值确实会导致分段错误。

【讨论】:

【参考方案2】:

long int A[n+2]=0; 在标准 C++ 中是不合法的。 There are a bunch of reasons 为此,我认为您偶然发现了其中一个。

允许可变长度数组的编译器遵循 C99 的示例,并且数组在堆栈上分配。堆栈是一种有限的资源,对于台式计算机,通常在 1 到 10 MB 之间。如果用户输入足够大小的n,则数组将占用太多堆栈或超出堆栈边界,从而导致Undefined Behaviour。然后,这种行为表现为访问内存的分段错误,该内存距离堆栈末端太远以至于不受程序控制。溢出堆栈时通常没有警告。通常,程序崩溃或数据损坏是您发现的方式,到那时挽救程序为时已晚。

另一方面,vector 从 freestore 分配它的内部缓冲区,在具有虚拟内存和 64 位寻址的现代 PC 上,freestore 非常大,如果你试图超过它可以分配的内容,则会引发异常.

另一个重要的区别是

long int A[n+2]=0;

可能没有对数组进行零初始化。 g++就是这种情况。第一个字节将设置为零,其余字节未初始化。这就是使用非标准扩展的诅咒。您不能指望标准所保证的行为。

std::vector 会将整个数组初始化为零或将数组设置为您告诉它使用的任何值。

【讨论】:

以上是关于代码使用向量成功运行,但使用数组显示错误的主要内容,如果未能解决你的问题,请参考以下文章

将数组转换为向量,我得到了一些未检测到的错误

通过引用传递向量使迭代算法以不同的方式运行

在 C++ 索引程序中使用向量时出现分段错误 11

为啥这个向量代码会出现分段错误?

编译JAVA程序成功但运行javac命令时出现错误

编译JAVA程序成功但运行javac命令时出现错误