【问题标题】:Class function changes other data in class cpp类函数改变类cpp中的其他数据
【发布时间】:2014-05-12 14:23:07
【问题描述】:

已解决!我发现了我的错误......我在最后发布了我的解决方案。很抱歉浪费了时间。

我已经有一段时间没有玩过 c++ 了。它从来都不是我的主要语言,所以我不熟悉细节。我有一个奇怪的错误弹出。当我调用 factorize() 时,它正在重置数字的符号。尽管标志从未被触摸过。

我找到了解决办法。在我的工作代码中,我添加了一个整数来保留和重置该值,但我认为我不应该这样做。我从下面的代码示例中删除了这两行。

我重置标志的地方: 此类的构造函数将符号设置为 0。它可以在 * 和 *= 运算符中设置为 0(如果它们都具有相同的符号)。仅当将 (unsigned long long) 值分配给对象时, = 运算符才将其设置为零(如果将其设置为等于另一个 FactorNumber,它会保留符号)。

就是这样。这些是我将符号设置为零的唯一地方。我不明白为什么这个函数会调用其中的任何一个。但是,我并不真正了解 c++ 在处理类时如何做事的细节。我不明白为什么符号不断重置为 0,但也许我做错了什么。有人知道为什么会这样吗?

class FactorNumber {
    private:
        unsigned long long number;
        unsigned long long factor_list[63];     // this is the max possible amount
        int number_of_factors;
        int sign;                               // 0=positive 1=negative
        void factorize();
[snipped irrelevant public function calls]
};    

void FactorNumber::factorize() {
    int x=0;
    for(x=0;x<64;x++) {
        factor_list[x]=0;
    }
    number_of_factors=0;
    unsigned long long current_factor=2;    // 64 bits in c++
    unsigned long long current_number=number;
    unsigned long max_factor=0;  // can never be more than 32 bits
    if (number>3) {
        max_factor=sqrt(current_number);
        while (current_factor<=max_factor) {
            if(current_number%current_factor) {
                if(current_factor>2) {
                    current_factor+=2;
                } else {
                    current_factor=3;   
                }
            } else {
                factor_list[number_of_factors++]=current_factor;
                current_number=current_number/current_factor;
                if(current_number%current_factor) {
                    max_factor=sqrt(current_number);
                }
            }
        }

        // If there is a number larger than one, add it to the array.
        if(current_number>1) {
            factor_list[number_of_factors]=current_number;
        } else {
            number_of_factors--;        // If not, we ignore this last number
        }
    } else {
        number_of_factors=0;
        factor_list[0]=number;
    }
}

我的错误是一个obiwan错误。我正在写超过我的数组的末尾(factor_list[63] 实际上并不存在),那是覆盖我的数据。只是巧合,这个重置标志并没有搞砸其他东西(或者可能是这样,但我还没有抓住它)。这就是我问这个问题的原因。并不是我无法解决它,我知道我的代码中某处存在错误。

将 for 循环条件更改为 x

【问题讨论】:

  • factor_list 一直到索引 62,而您在 factor_list 中的第一个 for 中一直到索引 64
  • 嗨,Brunk,请将解决方案添加为 Answer
  • @brasofilo 已经有 2 个答案了:)
  • @IosifMurariu,没问题;)...但问题不是发布答案的地方。如果 OP 不这样做,正常程序是回滚问题并将答案发布为社区 Wiki。
  • 我不能在 8 小时内发布答案,因为我在这里太新了。编辑原始问题是我提醒人们问题已解决的最快方法。 8小时过去了,我会在适当的地方写一个答案。

标签: c++ function class variables


【解决方案1】:

您在factorize() 中的第一个for 中溢出,因为您要到索引63,而最大索引(在类中声明为62(大小63))。实际上,每当您致电factor_list[X]=Y 时,您都有机会超越班级中的下一位成员。您总是需要验证数组索引!

unsigned long long factor_list[63]; // <----- indexes from 0 to 62 // <code omitted> factor_list[666] = 0; // <----- Oops! Overflowing (but it's still valid code)

另外,为什么在 C++ 中使用 C 样式的数组而不是 C++ 样式的数组? std::array 是更好的方法。

【讨论】:

  • 谢谢,我在您发布之前就找到了它并正在编辑它。 LOL C 是我学习的原始语言。所以,我倾向于以这种方式思考问题。我不知道 c++ 如何以不同的方式处理数组。我会仔细看看的。感谢您的提示。
  • @Brunk 与 C 完全没有区别,因此您的 C 代码中可能潜伏着很多错误。
  • @Brunk,如果您使用 MVS,您可以放置​​一个内存断点,以便在内存区域(分配给变量,即在您的情况下为 sign)被修改时触发。
  • 谢谢。我已经有一段时间没有编写太多代码了。我已经远离它了。通常我知道这些错误并小心避免它们。实际上出现了这个问题,因为我最初将数组的大小设置为 64。当我意识到 2^64-1 中永远不可能有 64 个素因子时,我更改了它并添加了该评论,最大值为 63。我从来没有去改变了循环。我应该做的,是为那个硬编码的值使用#define,所以它们都相互改变了。
  • 或者你可以使用一个常量来代替#define (const int max = 3; int myArray[max]; // &lt;--- this works :)
【解决方案2】:

factor_list 中有 63 项。

这个循环

for(x=0;x<64;x++) {
     factor_list[x]=0;
}

写信给 64 long longs

最后一个赋值 factor_list[63] 覆盖了存储在数组之后的变量,将 sign 设置为 0。

更改循环索引。

您可能还想添加不会将number_of_factors 增加太多的检查。

【讨论】:

  • number_of_factors 不应超过 62,主要是因为 0 和 (2^64-1) 之间的最大因子数量为 2^63。所有其他数字的因子计数都低于此值。例如,2^64-1 有 7 个因子(3,5,17,257,641,65537,6700417)。
  • 嗯,在这种情况下,这是一个非常可靠的假设。实际上,在 0 和 2^64-1 之间不存在具有超过 63 个质因数的数字,这是一个数学上的确定性。唯一可能出现的问题是如果 C++ 决定更改 (unsigned long long) 的大小,在这种情况下大于 2^64-1 的数字是可能的,并且可能有超过 63 个素因数。
  • @Brunk 实际上是为了防止错误,因为很难一眼看出代码是否正确。假设您的代码不会包含错误是危险的。
  • 我明白这一点。在这种情况下,我已经足够仔细地分析了循环,以确保 number_of_factors 在一种情况下(2^63)只能达到 63,并且此时的 current_number 将为 1,这将立即将 number_of_factors 减回到 62。我已经可以肯定的是,用边缘情况测试了这个循环,比如那个。为不可能发生的事情添加测试只会使此功能的效率低于现有水平。
  • 我并没有相反的意思。你肯定是对的,测试会使这段代码更加防弹。但是,它不是生产代码,也不是故意的。已经存在已知的错误(例如,我的 * 运算符不检查以确保产品适合 64 位)。我最终会清理它。对于一个数字,这个循环可以运行多达 2^30 次,这让我想尽可能保持精简。它也将被相当频繁地使用。
【解决方案3】:

如前所述,我正在写超出数组末尾的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多