C++ 查找素数和时出现内存错误

C++ 查找素数和时出现内存错误,c++,c++11,primes,C++,C++11,Primes,问题:给定偶数(大于2),返回两个素数,其和将等于给定的数。 解决方案:使用eratosthenes筛,找到给定数的所有素数。然后找到一对和给定数相等的数。 代码: 我无法理解为什么会发生这种情况以及它的解决方案是什么?让x=184。然后primes.size()为185。第一个循环迭代到i=13。13是质数。第二个循环迭代到j=171。在循环中,您可以访问素数[2223]。这是一个越界写入,导致UB。因此,您会得到损坏的动态内存和断言 看起来你在循环条件中输入了一个错误,你想要i*jLetx=

问题:给定偶数(大于2),返回两个素数,其和将等于给定的数。 解决方案:使用eratosthenes筛,找到给定数的所有素数。然后找到一对和给定数相等的数。 代码:


我无法理解为什么会发生这种情况以及它的解决方案是什么?

x=184
。然后
primes.size()
为185。第一个循环迭代到
i=13
。13是质数。第二个循环迭代到
j=171
。在循环中,您可以访问
素数[2223]
。这是一个越界写入,导致UB。因此,您会得到损坏的动态内存和断言


看起来你在循环条件中输入了一个错误,你想要
i*jLet
x=184
。然后
primes.size()
为185。第一个循环迭代到
i=13
。13是质数。第二个循环迭代到
j=171
。在循环中,您可以访问
素数[2223]
。这是一个越界写入,导致UB。因此,您会得到损坏的动态内存和断言


看起来您在循环条件中输入了错误,您希望
i*j使用
素数[i*j]=0
查找素数时,无效索引超过了向量大小,这就是此代码崩溃的原因。您可以将此更正为

for (int i = 2; i <= int(sqrt(A)); i++)
{
    if (primes[i] == 1)
    {
        for (int j = 2; i * j <= A; j++)
        {
            primes[i * j] = 0;
        }
    }
}

for(int i=2;i如果
素数[i*j]=0
在查找素数时,存在超过向量大小的无效索引,这就是此代码崩溃的原因。您可以将其更正为

for (int i = 2; i <= int(sqrt(A)); i++)
{
    if (primes[i] == 1)
    {
        for (int j = 2; i * j <= A; j++)
        {
            primes[i * j] = 0;
        }
    }
}

用于(int i=2;我在调试器中运行代码。此外,打开诊断以检测对容器的超出范围的访问。找出它崩溃的地方应该很容易。使用调试信息构建并使用,例如,找出何时何地超出范围。这一次,它也是一个mem corrupt。GCC有有用的调试编译器扩展,通过定义
\u GLIBCXX\u DEBUG
位于文件顶部。您的第一个循环
为[i*j]加素数=0;
超出了调试器中代码的向量长度。此外,打开诊断以检测对容器的超出范围的访问。找出它崩溃的位置应该很容易。使用调试信息构建并使用,例如,找出您何时何地越界。这一次,它也是一个mem corrupt。GCC具有有用的调试编译器,例如xtension,通过在文件顶部定义
\u GLIBCXX\u DEBUG
来启用。您的第一个循环
为[i*j]加素数=0;
超过向量长度由于向量
arr
默认情况下将被排序,因此您可以使用更有效的方法查找两个和等于某个数字的元素。默认情况下,向量
arr
将被排序,因此,您可以使用更有效的方法查找两个和相等的元素到一定数量
for (int i = 2; i <= int(sqrt(A)); i++)
{
    if (primes[i] == 1)
    {
        for (int j = 2; i * j <= A; j++)
        {
            primes[i * j] = 0;
        }
    }
}