访问未初始化的值,很可能是在向量中进行的

时间:2019-04-17 22:39:28

标签: c++ vector

我正在做一个练习,需要找到一个正整数pq,它们是另一个自然数n的因数。 遵循公式n=pq*q,其中p是 squarefree 数。

但是,对于程序的某些实例,我的编译器检测到一个内存错误,表明我正在访问未初始化的值。

我尝试的逻辑如下。首先,我采用了需要分解的数字(将其命名为n)。接下来,我找到了所有数为n的因子,并将它们放在向量中。之后,检查该向量的每个元素是否都是 squarefree 。如果为true,则将元素放在另一个向量中(n个无平方因子的向量)。之后,遍历平方无因数向量的每个元素,并求解方程q=sqrt(n/p),其中p是向量中的平方无因数。另外,我检查条件if(int(sqrt(n/p))==sqrt(n/p)),因为平方根必须是一个正整数。

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// Function that checks if the number is squarefree

bool isSquareFree(int n)
{
    if (n % 2 == 0)
        n = n / 2;
    if (n % 2 == 0)
        return false;
    for (int i = 3; i <= sqrt(n); i += 2)
    {
        if (n % i == 0)
        {
            n = n / i;
            if (n % i == 0)
                return false;
        }
    }
    return true;
}

void Factorise_the_number(int n, int &p, int &q)
{
    if (n <= 0)
        return 0;
    vector<int> factors(0); // vector of factors
    vector<int> sqfree_factors(0); // vector of squarefree factors
    int sqfree_number; // the number "p"
    int squared; // is essentially the number "q"

    for (int i = 1; i <= n / 2; i++)
    {
        if (n % i == 0)
            factors.push_back(i); // takes all factors of the number "n"
    }

    for (int i = 0; i < factors.size(); i++)
    {
        if (isSquareFree(factors.at(i)))
            sqfree_factors.push_back(factors.at(i));
    } // checks if each factor is squarefree. if yes, put it in a separate vector

    for (auto x : sqfree_factors)
    {

        if (int(sqrt(n / x)) == sqrt(n / x))
        { // if true, we found the numbers
            squared = sqrt(n / x);
            sqfree_number = x;
            break;
        }
    }

    p = sqfree_number;
    q = squared;
}

int main()
{

    int n, p = 0, q = 0;
    cin >> n;

    Factorise_the_number(n, p, q);
    cout << p << " " << q;

    return 0;
}

例如,如果我输入数字99,则我的程序可以工作,但是如果输入39,则该程序不工作。谁能提供任何见识?

谢谢!

1 个答案:

答案 0 :(得分:0)

正如您所说,对于39而言,它是行不通的。您是否检查过39的功能?您应该这样做,因为这是调试程序的最佳方法。

让我们一起看一下。首先,它尝试查找所有因素,然后找到1、3和13:这看起来不错。

然后,它检查这些数字中的每个数字是否都是无平方的,并且都为:这看起来也是正确的。

然后,它检查是否有任何平方自由因数满足您要寻找的相等性。它们都不起作用(39是3 x 13,它不可能包含平方因子)。这意味着if (int(sqrt(n / x)) == sqrt(n / x))永远不会为真,并且该块永远不会运行。此时sqfree_numbersquared的值是多少?它从未被初始化。使用未初始化的值会导致“未定义的行为”,也就是说,您的程序可以执行任何操作。在这种情况下,pq最终将包含随机值。

如何解决?考虑一下:如果n不满足您的等式,也就是说,它不能表示为pq * q,那么程序应该输出什么呢?您现在的输出是否有意义?否。这意味着您必须修改程序,使其涵盖您没有考虑的情况。

一种方法是在最后一个bool found = false;循环之前添加一个for。找到因素后,将其断开之前,将该变量设置为true。然后,在循环之外检查它:是true吗?然后,您可以返回正确的值。但是,如果它仍然是false,则意味着等式不成立,并且您将无法返回正确的值。您必须找到一种向呼叫者发送信号的方法(这是您的main函数),以便它可以打印适当的消息。

您怎么发信号呢?通常,您可以更改Factorise_the_number(顺便说一句,函数名称应以小写字母开头;类通常使用大写字母)以返回bool。或者,您可以使用一个技巧:为pq返回一个特殊值,该值不能作为计算结果。像-1。然后,在打印之前,检查:如果值是-1​​,则表示该数字不能表示为pq * q。